当一个网页被载入到浏览器时,浏览器会首先分析这个HTML 文档,然后会依照这份HTML 的内容解析成DOM (Document Object Model,即文件对象模型)
JS 如何操控网页——浏览器在 window 上面加 document 。
DOM 一个规范,换言之,只要遵守这样的规范,不管是什么平台或者是什么语言开发,都可以通过DOM 提供的API 来操作DOM 的内容、结构与样式。
获取元素/标签
window.id号
或 直接id号
document.querySelector('#id号')
- 想找到满足条件的 ——
document.querySelector('条件')
例如:document.querySelector('div > span:nth-child(2)')
; - 找到全部满足条件的 ——
document.querySelectorAll('条件')[下标]
如果要兼容IE的可用 document.getElement(s)ByXXX ,比如: - document.getElementByld('id号')
- document.getElementsByTagName('div')[0] —— div 的所有标签的第一个。
- document.getElementsByClassName('red')[0] —— class类是red的部分。
获取特定元素
- 获取 html 元素 ——
document.documentElement
- 获取 head 元素 ——
document.head
- 获取 body 元素 ——
document.body
- 获取窗口(窗口不是元素)—— window
- 获取所有元素 ——
document.all
获取到的元素显然是一个对象,已 div 为例,可以用console.dir(div1)
来看原型链。
节点Node
MDN有完整描述,只读属性 Node.nodeType 表示的是该节点的类型,常用的有:(比较重要的有 1 和 2)
- 1 —— 表示元素Element,也叫标签Tag。
- 3 —— 表示文本 Text
- 8 —— 表示注释 Comment
- 9 —— 表示文档 Document
- 11 —— 文档片段DocumentFragment
节点的增删改查
节点的增
- 创建一个标签节点,例
let div1 = document.createElement('div')
document.createElement('style')
document.createElement('script')
document.createElement('li')
- 创建一个文本节点,例
text1 = document.createTextNode('你好')
- 标签里插入文本,例
div1.appendChild(text1)
div1.innerText='你好' 或者 div1.textContent = '你好'
//但是不能用 div1.appendChild('你好')
- 插入到页面中
创建的标签默认处于 JS 线程中,必须将其插到 head 或者 body 里面,才会生效。例如
document.body.appendChild(div)
或者已在页面的元素.appendChild(div)
。
appendChild
一个元素不能出现在两个地方,除非复制了一份。
例如:页面中有 div#test1 和 div#test2,创建了一个div标签,再通过
test1.appendChild(div)
test2.appendChild(div)
则div最后是在test2 。
复制节点:
div2 = div1.cloneNode(true)
// ()里面的 true 指深拷贝,会复制子节点
节点的改
- 改 id ——
div2.id = 'xxx'
- 改 class :
div.className = 'red' // 覆盖原有内容
div.classList.add('green') // 不覆盖原有内容,在原有内容的基础上添加green
div.className += 'blue' // 不覆盖原有内容,在原有内容的基础上添加blue
- 改style:
div.style = 'color:blue' // 覆盖原有内容
div.style.color = 'blue' // 推荐写法
- 关于大小写:
例如
div.style.background—color
,由于 JS 不支持中划线,会被认为是div.style.background
减color
。所以在使用时会删除中划线,并且原来中划线后的第一个字母会大写 ——div.style.backgroundColor = 'blue'
。 - data 属性: 以 data-x=test 为例, data-x —— 属性名,test —— 属性值。
添加属性:div.setAttribute('data-x','test')
。
获取属性值:div.getAttribute('data-x')
或者 div.dataset.x
。
更改属性值:div.dataset.x = 'xxx'
。
- 读属性:直接
.属性名
会得到浏览器加工的值,但是.getAttribute('属性名')
会得到准确值。
改内容
- 改文本内容:
div.innerText = 'xxx'
和div.textContent = 'xxx'
- 改HTML内容:
div.innerHTML = '<strong>重要内容</strong>'
,但是 .innerHTML 里面不能超过2万字符。 - 改标签:
div.innerHTML = '' //先清空
div.appendChild(div2) //再加内容
- 改父节点:
newParent.appendChild(div)
节点的查
- 查父节点:
node.parentNode
或者node.parentElement
。 - 查祖父节点:
node.parentNode.parentNode
- 查子节点:
node.childNodes
或者node.children
,但是更推荐使用后者,因为前者会算上空格。当子代变化时,两者也会实时变化,但是:let c = document.querySelectorAll
中的 c 值就不会变化了。 - 查同代的子节点:
node.parentNode.childNodes
和node.parentNode.children
,还需要排除节点自己本身。 - 查子节点的老大:
node.firstChild
。 - 查子节点的老幺:
node.lastChild
。 - 查看上一个哥哥:
node.previousSibling
或者node.previousElementSibling
,前者可能会将文本也认为是节点,后者就局限为元素了。 - 查看下一个节点:
node.nextSibling
和node.nextElementSibling
,前者也是可能将文本误认为是节点,后者就只是指元素了。 - 遍历:以遍历一个div里面的所有元素为例,
travel1 = (node,fn) => {
fn(node)
if(node.children){
for(let i = 0;i < node.children.length;i++){
travel1(node.children[i],fn)
}
}
}
travel1(div1,(node) => console.log(node))