当一个网页被载入到浏览器时,浏览器会首先分析这个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)来看原型链。DOM 树_DOM

节点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')  // 不覆盖原有内容,在原有内容的基础上添加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))复制代码