DOM是一棵树
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<header>
<h1>文字内容</h1>
</header>
<main>
<h2></h2>
<p></p>
</main>
</body>
</html>
js操作dom
浏览器在window对象上添加了document属性,使得js有操作dom的功能
js使用document操作网页,这就是Document Object Model 文档对象模型
获取元素
API
- window.id 或者直接 id
<input id="keyword">
<!-- js -->
keyword//或者 window.keyword
- document.getElementById("id")
<input id="keyword">
<!-- js -->
document.getElementById("keyword")
- document.getElementsByTagName('div')
- document.getElementsByClassName('test')
- document.querySelector("#id")
- document.querySelectorAll(".test")
推荐使用
querySelector 和 querySelectorAll
兼容ie使用getElement(s)ByXXX
获取特定元素
获取html元素
document.documentElement
获取head元素
document.head
获取body元素
document.body
获取窗口
window
获取所有元素
- document.all
- 这个document.all 在非ie浏览器中是falsy值
if(document.all){
console.log("ie浏览器")// 只能在ie浏览器里面运行
} else {
console.log("其他浏览器")// 只能在非ie浏览器运行
}
dom节点也是对象
节点
- MDN有完整描述,x.nodeType得到一个数字
- 1 表示元素Element,也叫标签Tag
- 3 表示文本Text
- 8 表示注释Comment
- 9 表示文档 Document
- 11 表示文档片段 DocumnentFragment
节点的增删改查
增
- 创建一个标签节点
let div1 = document.createElement("div");
document.createElement('style')
document.createElement('script')
document.createElement('li')
- 创建一个文本节点
text1 = document.createTextNode("你好")
- 标签里面插入文本
div1.appendChild("text1")
div1.innnerText = "hello"
div1.textContent = "hello"
不能使用div1.appendChild("hello")
- 插入页面中
1 你创建的标签默认处于js线程中
2 你必须把它插入到head或者body里面
3 document.body.appendChild(div)
4 已经存在于页面的元素.appendChild(div) - test
let div = document.createElement('div')
test1.appendChild(div)
test2.appendChild(div)
最后div处于test2
删
两种方法
- childNode.parentNode.removeChild(childNode)
- childNode.remove()
改
改写
- 改class: div.className = "red blue"
不能使用 div.class = "red blue"
- 追加: div.classList.add('red')
- 改style: div.style = "width: 100px; color: blue"
- 改写style部分: div.style.width = "200px"
div.style.backgroundColor = "red"
- 改data-*属性,如data-x: div.dataset.x = 'wt'
读取
- div.classList / a.href
- div.getAttribute("class") / a.getAttribute('href')
- 两种方法都可以,但是值可能不同
改事件处理函数
div.onclick 默认为null
- 默认点击div不会有任何事情发生
- 但是如果你把div.onclick 改为一个函数fn
- 那么点击div的时候,浏览器就会调用这个函数
- 并且是这样调用的fn.call(div, event)
- div 会被当做this
- event则包含了点击事件的所有信息,如坐标
改内容
改文本内容
div.innerText = "xx";
div.textContent = "xx"
改写HTML内容
div.innerHTML = "<strong>重要内容</strong>"
改标签内容
div.innerHTML = ""// 先清空内容
div.appendChild(div2)// 在追加内容
查
查父亲
node.parentNode 或者 node.parentElement
查爷爷
node.parentNode.parentNode
查子代
node.childNodes 或者 node.children
查兄弟姐妹
node.parentNode.childNodes 需要手动排除自己
查看第一个元素
node.firstChild
查看最后一个
node.lastChild
查看上一个
node.previousSibling
查看下一个
node.nextSibling
跨线程操作
各线程各司其职
- JS 引擎不能操作页面, 只能操作js
- 渲染引擎不能操作js,只能操作页面
跨线程通信
- 浏览器发现js在body里面加了一个div1对象
- 浏览器就会通知渲染引擎在页面里新增了一个div元素
-
新增的div元素所有属性都照抄div1的对象
插入新的标签
在div1放入页面之前
对div1的所有操作都是属于js线程操作
在div1放入页面时
- 浏览器会通知渲染线程在页面中渲染div1对应的元素
div1放入页面之后
- div1的所有操作都可能触发重新渲染
- div1.id = "newId" 可能会重新渲染,也可能不会
- 如果连续对div1多次操作,浏览器可能会合并成一次操作,也可能不会
属性同步
标准属性
- div1的标准属性的修改,会被浏览器同步到页面中
- 比如id、className、title等
data-*属性
- 同上
非标准属性
- 对非标准属性的修改,只会停留在js线程中
-
不会同步到页面
property attribute
property属性
js线程中div1的所有属性
attribute
渲染引擎中div1对应标签属性,叫做attribute
区别
- 大部分时候,同一个元素property和attribute值相等
- 但是如果不是标准属性,那么只会在最开始的时候相等
- 注意attribute只支持字符串
- property支持字符串、布尔等类型