DOM编程
目录
前置知识网页就是一棵DOM树JS如何操作这棵树DOM元素节点的增删改查DOM操作是跨线程的Property VS Attribute
一、前置知识
- 理解简单的JS语法
- JS的七种数据类型:
number、string、bool、symbol、undefined、null、Object - JS五个falsy值:
''、undefined、null、0、NaN - 简单的CSS布局
二、网页是一棵DOM树
- 代码+图解
文字1
文字2
文字3文字4文字5
``` 三、JS如何操作这棵树?
使用document操作网页这就是DOM(Document Object Model)文档对象模型
四、DOM元素
- 获取元素(标签)
document.getElementById('xxx'); . document.getElementsByTagName('div')[0]; . document.getElementsByClassName('red')[0]; . document.querySelector(''); | 需要遵守选择器的样式书写 如:'#id_1'、'.class_1'、 . document.querySelectorALL(); |同上 - 获取特定元素
1、获取html元素 document.documentElement 2、获取head元素 document.head 3、获取body元素 document.body 4、获取窗口 |窗口不是元素 window 5、获取所有元素 document.allwindow.all: 是第6个falsy值原因:因为window.all最早是IE发明的,早期的前端为了区分IE和其他浏览器,就一般如下设置。为了区分是IE还是非IE浏览器。if(window.all){ console.log("这些代码只能在IE里面运行"); } else{ console.log("这些代码只能在非IE里面运行"); }
- 问题来了:获取到的元素到底是个啥?
显然获取到的元素是个对象抓一只div对象来看看都有啥console.dir(div);div的6层原型链
-
节点?元素?傻傻分不清楚
使用
nodeType方法可以打印出节点的值1表示元素ELement,也叫标签Tag3表示文本Text8表示注释Comment9表示文档Document- 更多节点值
五、节点的增删改查
1、增
- 创建一个标签节点
let div1=document.createElement('div'); document.createElement('style'); document.createElement('script'); document.createElement('li'); - 创建一个文本节点
text1=document.createTextNode('你好'); - 插入创建的节点:
坑1:一个元素不能同时出现在(插入)两个地方,除非复制一份。div1.appendChild(text1); | 在div1标签里面插入文本节点text1 document.body.appendChild(div1); | 在body里面插入div1标签 document.head.appendChild(div1); | 在head里面插入div1标签
2、删
- 删除节点:
坑2:删除之后的节点被移除DOM树,但还在内存中,依然可以调用它再将其添加回来旧方法 | parentNode.removeChild('待删除的儿子节点') 新方法 | 待删除的节点.remove();
3、改
- 写标准属性:
注意:js中不识别'-'这个字符,所以遇到'-'就将'-'后面第一个字母大写,如:background-color --> backgroundColor改class | div.style.className='red blue'; --> 全覆盖 改class | div.classList.add('red'); 改style | div.style='width:100px;color:blue'; --> 全覆盖 改style | div.style.width='200px'; --> 推荐 改data-*属性 | div.dataset.x='frank'; - 读标准属性:
下面两种方法都可以读属性,但某些情况下的值可能会不同。默认方法 | div.classList/a.href getter/setter方法 | div.getAttribute('class')/a.getAttribute('href'); - 改文本内容
div.innerText='你好,世界!'; div.textContent='你好,世界!'; - 改HTML内容
div.innerHTML='<strong>重要的内容</strong>'; - 改标签
div.innerHTML=''; | 先清空内容 div.appendChild(div2); | 再添加内容 - 改父元素?
newParent.appendChild(div); | div的父元素变成newParent,并且从原来的地方消失。
4、查
- 查爸爸
node.parentNode | node.parentElement - 查爷爷
node.parentNode.parentNode - 查子代:
坑1:当子代变化时,两者也会实时变化,例如遍历的数组长度lengthnode.childNodes | node.children - 查兄弟姐妹
node.parentNode.childNode | 注意要排除自己 node.parentNode.children | 注意要排除自己 - 查看老大、老幺
node.firstChild node.lastChild - 查看上一个节点元素
node.previousSibling - 查看下一个节点元素
node.nextSibling - 遍历一个div里面的所有元素
travel = (node,fn)=>{ fn(node); if(node.children){ for(let i=0;i<node.children.length;i++){ travel(node.children[i],fn); } } } travel(div,(node)=>{ console.log(node); })
六、DOM操作是跨线程的
-
跨线程操作
JS引擎不能操作页面,只能操作JS渲染引擎不能操作JS,只能操作页面例如执行如示代码:document.body.appendChild(div1) JS 是如何改变页面的?
-
跨线程通信
当浏览器发现JS在body里面加了一个div对象浏览器就会通知渲染引擎在页面里也新增一个div元素
-
插入新标签的完整过程
在div1放入页面之前对div1进行的所有操作都是在JS线程中进行的在div1放入页面之时浏览器发现了JS的意图,通知渲染线程在页面中渲染div1对应的元素把div1放入页面之后当你想对div1再次进行操作时,都会有可能触发重新渲染
-
属性同步
标准属性:如id,className,title等data-*属性非标准属性:除开1,2两点的其他自定义属性自动属性同步
``` id 一开始为 test,后来改为 frank
你会发现页面中 id 变为 frank
data-x 属性一开始为 test,后来改为 frank
你会发现页面中的 data-x 变成了 frank
x 属性一开始为 test,后来改为 frank
你会发现页面中的 x 还是 test
七、Property VS Attribute
-
property属性JS 中div1的所有属性,叫做div1的property
-
attribute属性渲染引擎中div1对应标签的属性,叫做attribute
-
二者的区别大部分时候,同名的property和attriubte值相等。但如果不是标准属性,两者的值只会在一开始的时候相等attribute: 只支持字符串类型property: 支持字符串、布尔等类型