JavaScript 的 DOM 编程

165 阅读2分钟

JS 用 document 操作网页,这就是 Document Object Model 文档对象模型 (DOM)。DOM 编程就是把网页抽象成文档对象,然后对其进行操作。

1. 获取元素

1.1 获取任意元素

window.document // 可以获取到整个网页的根元素。
window.id名 / id名  
document.getElementById('id名')
document.getElementsByTagName('div')[0]
document.getElementsByClassName('类名')[0]
document.querySelector('#id名')
document.querySelectorAll('.类名')[0]

1.2 获取特定元素

document.documentElement // 获取 html 元素
document.head // 获取 head 元素
document.body // 获取 body 元素
window // 获取窗口(窗口不是元素)
document.all // 获取所有元素, document.all 是一个 falsy 值

1.3 一个 div 的原型链

第一层原型:HTMLDivElement.prototype

第二层原型:HTMLElement.prototype

第三层原型:Element.prototype

第四层原型:Node.prototype

第五层原型:EventTarget.prototype

第六层原型:Object.prototype

每一层的原型都会给这个 div 添加属性和方法。

2. 节点的增删改查

节点 Node 包括以下几种:

  • 元素 Element ,也叫标签 tag
  • 文本 Text
  • 注释 Comment
  • 文档 Document
  • 等等...

2.1 增

创建一个标签节点

let div1 = document.createElement('div') // 创建一个 div
document.createElement('style')
document.createElement('script')
document.createElement('li')

创建一个文本节点

text1 = document.createTextNode('你好')

标签里面插入文本

div1.appendChild(text1)
div.innerText='你好' / div1.textContent='你好'

新创建的标签默认处于 JS 线程中,必须插入到 head 或者 body 中才会生效。

2.2 删

div1.parentNode.removeChild(div1) 
div1.remove() // 新版,要考虑兼容性问题

如果一个 node 被移出页面(DOM 树),它能够被再次加到页面中。

2.3 改

改 class : 
div.className = 'red blue' (会把原来的的className 覆盖掉)
改 class : 
div.classList.add('red') (不会覆盖原来的 className)
改 style :
div.style = 'width:100px;color:red;'
改 style 的一部分:
div.style.width = '200px'
改 文本内容:
div.innerText='xxx'
改 文本内容:
div.textContent='xxx' // 两种方法几乎没有区别
改 HTML 内容:
div.innerHTML='<p>标题</p>
改 标签:
div.innerHTML='' // 先清空
div.appendChild(div2) // 再加内容
newParent.appendChild(div) // 将 div 从旧标签中删除,然后加入到 newParent 标签里面

读标准属性

div.id 
div.style
div.className
div.classList
div.getAttribute('class')  // getAttribute 会更加正式,可以确保取得的值不会被浏览器改动
a.getAttribute('herf')

2.4 查

查父级
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)

3. DOM

DOM 操作是跨线程操作的。JS 引擎不能操作页面,只能操作 JS。渲染引擎不能操作 JS, 只能操作页面。当浏览器发现 JS 在 body 里面加了个 div1 对象,浏览器会通知渲染引擎在页面里面也新增一个 div 元素,新增的 div 元素所有属性都会照抄 div1 对象, DOM 操作慢是因为 DOM 操作是跨线程的,渲染页面有可能会重新对页面进行渲染。

Property 是属性

JS 线程中 div1 的所有属性,叫做 div1 的 property。

attribute 也是属性

渲染引擎中 div1 对应标签的属性,叫做 attribute。