当一个网页被载入到浏览器时,浏览器会首先分析这个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(这是第6个 falsy 值)
获取到的元素显然是一个对象,已 div 为例,可以用console.dir(div1)来看原型链。
节点NodeMDN有完整描述,只读属性 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') // 不覆盖原有内容,在原有内容的基础上添加greendiv.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))复制代码