DOM编程(Document Object Model)
如何获取元素(标签)
获取任意元素
-
简单写法
-
兼容ie专用
- document.getElementByld(‘id‘)
- document.getElementsByTagName(‘div‘)[0]
- document.getElementsByClassName(‘class‘)[0]
-
工作用
- document.querySelector(‘80%情况下css选择器咋写就咋写‘)
- document.querySelectorAll(‘.red‘)[0]
获取特定元素
- 获取根元素html元素: document.documentElement
- 获取head元素: document.head
- 获取body元素: document.body
- 获取窗口(不是一个元素):window
- 获取所有元素:document.all
看一个div对象的原型链
console.dir(div1)看原型链
- 自身属性: className、id、style 等等
- 第一层原型HTMLDivElement.prototype: 这里面是所有div共有的属性,不用细看
- 第二层原型HTMLElement.prototype: 这里面是所有HTML标签共有的属性,不用细看
- 第三层原型Element.prototype: 这里面是所有XML、HTML 标签的共有属性,你不会以为浏览器 只能展示HTML吧
- 第四层原型Node.prototype: 这里面是所有节点共有的属性,节点包括XML标签文本注释、 HTML标签文本注释等等
- 第五层原型EventTarget.prototype: 里面最重要的函数属性是addEventListener
- 最后一层原型就是Object.prototype了
图示
节点Node
元素Element(标签Tag)节点--1
文本Text节点--3
文档Document节点--9
节点Node的增删改查
增节点
-
创建一个标签节点
- document.createElement(‘标签名‘)
- let div1 = document.createElement(‘div‘)
-
创建一个文本节点
- text1 = document.createTextNode("你好")
-
appendChild() 方法
- 添加新的子节点
- node.appendChild(node)
- 一个元素不可以出现在两个地方,除非复制
-
标签里面插入文本
- div1. appendChild(text1) 必须加文本节点的名字,不可以加文本的内容
- div1.innerText=‘你好‘ Node原型提供的接口
- div1.textContent =‘你好‘ Element提供的接口
-
插入页面中
- 默认处于js线程中
- 必须插入head或者body中才生效document.body.appendChild(div)
- 或者已在页面中的元素.appendChild(div)
删节点
- 旧方法: parentNode.removeChild(childNode)
- 新方法: childNode.remove() 直接删除
改
-
改节点的标准属性
-
改class
- div.className= ‘red blue‘ (全覆盖)
- div.className += ‘blue‘ (增加)
- div.classList.add(‘blue‘)(增加)
-
改style
- div.style = ‘width: 100px; color: blue;‘(全覆盖)
- 改style的一部分: div.style.width = ‘200px‘
- 大小写: div.style.backgroundColor = ‘white‘ C大写表示-c
-
改data-*属性
- div.dataset.x = ‘frank‘(没人用了)
-
读标准属性
- div.classList / a.href(会给你把路径补充完整)前面加http
- div.getAttribute(‘class‘) / a.getAttribute(‘href‘)(原封不动的给你)
-
改节点的事件处理函数
-
div.onclick默认为null
- 默认点击div不会有任何事情发生
- 但是如果你把div.onclick改为一个函数fn,那么点击div的时候,浏览器就会调用这个函数
- 并且是这样调用的fn.call(div, event)
- div会被当做this
- event则包含了点击事件的所有信息,如坐标
- div.addEventListener 是div.onclick的升级版
-
改子节点
-
改文本内容
- div.innerText = ‘xxx‘
- div.textContent= ‘xxx‘
-
改HTML内容
-
改标签
- div.innerHTML = ‘‘//先清空
- div.appendChild(div2) //再加内容
-
改父节点
- newParent.appendChild(div)
- 直接这样就可以了,直接从原来的地方消失
查节点
-
查自己
-
查爸爸
- node.parentNode
- node.parentElement
-
查爷爷
- node.parentNode.parentNode
-
查子代
-
所有
- node.childNodes(会把你不想要的空格也当成一个文本子节点)
- node.children(这个不会,只是元素节点,优先使用)
- 当子代变化时,两者也会实时变化
- document.querySelectorAll(‘.red‘)[0]不会实时更新
-
一个
- node.children[0]
- 查看第一个node.firstChild
- 查看最后一个node.lastChild
-
查兄弟姐妹
-
查所有兄弟姐妹
- node.parentNode.childNodes但自己也在里面,要排除自己和所有文本节点
- node.parentNode.children但自己也在里面,要排除自己
- 排除自己:要用for循环遍历所有子节点,然后把自己排除出去
-
查特定的兄弟姐妹
- 查看上一个哥哥/姐姐node.previousSibling(节点兄弟,可能为文本节点)
- 查看上一个哥哥/姐姐node.previousElementSibling(元素兄弟)
- 查看下一个弟弟/妹妹node.nextSibling(节点兄弟,可能为文本节点)
- 查看下一个弟弟/妹妹node.nextElementSibling(元素兄弟)
-
查看一个节点里所有的元素
DOM操作是跨线程的
各线程各司其职
- JS引擎不能操作页面,只能操作JS
- 渲染引擎不能操作JS,只能操作页面
跨线程通信
- document.body.appendChild(div1)---这是一句跨线程的DOM操作
- 当浏览器发现JS在body里面加了个div1对象
- 浏览器就会通知渲染引擎在页面里也新增一个div元素
- 新增的div元素所有属性都照抄div1对象
插入新标签的完整过程
-
在div1放入页面之前
- 你对div1所有的操作都属于JS线程内的操作
- let div1 = document.createElement(‘div‘)
div1.textContent = ‘hi‘
-
把div1放入页面之时
- document.body.appendChild(div1)
- 浏览器会发现JS的意图,就会通知渲染线程在页面中渲染div1对应的元素
-
把div1放入页面之后
- 你对div1的操作都有可能会触发重新渲染
- div1.id = ‘newid‘可能会重新渲染,也可能不会
- div1.title= ‘new‘可能会重新渲染,也可能不会
- 如果你连续对div1多次操作,浏览器可能会合并成一 次操作,也可能不会(之前在动画里提到过)
-
属性同步
-
标准属性
- 对div1的标准属性的修改,会被浏览器同步到页面中
- 比如id、className、 title 等
-
data-*属性 同上
-
非标准属性
- 对非标准属性的修改,则只会停留在JS线程中,不会同步到页面里
- 比如x属性,示例代码
-
启示
- 如果你有自定义属性,又想被同步到页面中,请使用
- data-作为前缀
-
Property V.S. Attribute
DOM编程
原文:https://www.cnblogs.com/justcho/p/13472564.html