获取元素的 API
- window.idxxx 或者直接 idxxx
- document.getElementById('idxxx')
- document.getElementsByTagName('div')[0]
- document.getElementsByClassName('red')[0]
- document.querySelector(‘#idxxx’)
- document.querySelectorAll('.red')[0]
获取特定的元素
获取 html 元素
- document.documentElement
获取 head 元素
- document.head
获取 body 元素
- document.body
获取窗口(窗口不是元素)
- window
获取所有元素
- document.all
- 第6个 falsy 值
查看一个 div 对象的原型链
console.dir(div)看原型链
- 自身属性:className、id、style等等
- 第一层原型HTMLDivElement.prototype
这里面是所有div共有的属性,不用细看- 第二层原型HTMLElement.prototype
这里面是所有HTML标签共有的属性,不用细看- 第三层原型Element.prototype
这里面是所有XML、HTML标签的共有属性- 第四层原型Node.prototype
这里面是所有节点共有的属性,节点包括XML标签文本注释、HTML标签文本注释等等- 第五层原型EventTarget.prototype
里面最重要的函数属性是addEventListener- 最后一层原型就是Object.prototype
节点的 node 包括
- x.nodeType得到一个数字1表示元素Element,也叫标签Tag
- 3表示文本Text
- 8表示注释Comment9表示文档Document
- 11表示文档片段DocumentFragment
节点的增删改查
增
创建一个标签节点
- let div1 = document.createElement('div')
- document.createElement('style')
- document.createElement('script')
- document.createElement('li')
创建一个文本节点
- text1 = document.craeteElementTextNode('你好')
标签里插入文本
- div1.appendChild(text1)
- div1.innerText = '你好' 或者 div1.textContent = '你好'
- 但是不能用 div1.appendChild('你好')
插入页面中
- 创建的标签默认处于 JS 线程中
- 必须把它插到 head 或者 body 里面,才会生效
- document.body.appendChild(div)
- 或者已在页面中的元素.appendChild(div)
删
- 旧方法:parentNode.childChild(childNode)
- 新方法:childNode.remove()
改
写标准属性
- 改 class: div.className = ‘red blue’ (全覆盖)
- 改class: div.classList.add('red')
- 改style: div.style = 'width: 100px; color: blue;'
- 改style的一部分:div.style.width = '200px'
- 大小写: div.style.backgroundColor='white'
- 改data-*属性:div.dataset.x = 'abc'
读标准属性
- div.classList / a.href
- div.getAttribute('class') / a.getAttributr('href')
改事件处理函数
- div.onclick 默认为 null
- 默认点击div不会有任何事情发生
- 但是如果你把div.onclick改为一个函数fn那么点击div的时候,浏览器就会调用这个函数并且是这样调用的fn.call(div, event)
- div会被当做this
- event则包含了点击事件的所有信息,如坐标
div.addEventListener
- div.onclick的升级版
改文本内容
- div.innerText = 'xxx'
- div.textContent = 'xxx'
- 两者几乎没有区别
改HTML内容
- div.innerHTML= '<strong>重要内容</strong>'
改标签
- div.innerHTML="//先清空
- div.appendChild(div2)//再加内容
改爸爸
newParent.appendChild(div)
查
查爸爸
- node.parentNode 或者 node.parentElement
查爷爷
- node.parentNode.parentNode
查子代
- node.childNodes 或者 node.children
- 子代变化时,两者也会同时变化
查兄弟姐妹
- node.parentNode.childNodes 还要排除自己
- 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(div1, (node) => console.log(node))
DOM 跨线程操作
- 各线程各司其职
- JS引擎不能操作页面,只能操作JS
- 渲染引擎不能操作JS,只能操作页面
- 当浏览器发现JS在body里面加了个div1对象
- 浏览器就会通知渲染引擎在页面里也新增一个div元素
- 新增的div元素所有属性都照抄div1对象
跨线程操作图示
插入新标签的完整过程
在div1放入页面之前
- 对 div1所有的操作都属于JS线程内的操作
把div1放入页面之时
- 浏览器会发现JS的意图
- 就会通知渲染线程在页面中渲染div1对应的元素
把div1放入页面之后
- 对div1的操作都有可能会触发重新渲染
- div1.id = 'newld'可能会重新渲染,也可能不会
- div1.title = 'new'可能会重新渲染,也可能不会
- 如果连续对div1多次操作,浏览器可能会合并成一次操作,也可能不会
属性同步
标准属性
- 对div1的标准属性的修改,会被浏览器同步到页面中
- 比如id、className、title等
data-*属性
- 同上
非标准属性
- 对非标准属性的修改,则只会停留在JS线程中不会同步到页面里
- 如果有自定义属性,又想被同步到页面中,请使用data-作为前缀
图示
Property v.s. Attribute
property属性
- JS线程中div1的所有属性,叫做div1的 property
attribute也是属性
- 渲染引擎中div1对应标签的属性,叫做attribute
区别
- 大部分时候,同名的property和attribute值相等
- 但如果不是标准属性,那么它俩只会在一开始时相等
- 但注意attribute只支持字符串
- 而property支持字符串、布尔等类型
*本文为鲲游北冥的原创文章,著作权归本人和饥人谷所有,转载务必注明来源