likes
comments
collection
share

简述DOM中的API

作者站长头像
站长
· 阅读数 54

DOM(Document Object Model)文档对象模型,相较于直接操作 html 和 css,使用 DOM 可以动态的访问程序和脚本,使其更新内容。


我们如果使用 html 写一个文档,我们可以将其看作一个 树(Tree)

简述DOM中的API

简述DOM中的API

如果我们要操作这棵树,我们可以使用JS中的document来实现。


元素与节点

节点分为两种:标签,文本

通过 x.nodeType 可以得到一个数字

1表示Element,也叫Tag,标签 3表示文本 Text


获取元素

document.getElementById('xxx') //通过Id来获取
document.getElementsByTagName('div')[0] //通过标签名获取(获取第1个div标签)
document.getElementsClassName('red')[0] //获取第1个class='red'的元素

//以上方法只有在需要兼容IE的情况下才建议使用(因为太长了)
document.querySelector('') //获取元素(第一个遇到的)

document.querySelectorAll('div') //获取所有含有div的元素

document.querySelectorAll('div')[0] //获取第一个div标签

获取特定元素

document.documentElement //获取html元素
document.head //获取head元素
document.body //获取body元素
window //获取窗口,可通过window.onclick 对窗口进行监听
document.all //获取所有的标签

其中 document.all 可以被称为 第6个falsy值,因为早期只有IE浏览器支持document.all,所以其他浏览器会自动将其判断为false

简述DOM中的API

但现在IE这种情况已经不适用了

简述DOM中的API


获取到的元素是什么

简述DOM中的API

假如我们获取一个 div 元素,我们可以看到他是一个对象

并且,此对象拥有 6 层原型

div.__proto__ === HTMLDivElement.prototype
// 所有div的共同属性

HTMLDivElement.prototype.__proto__ === HTMLElement.prototype
//所有HTML元素的共同属性

HTMLElement.prototype.__proto__ === Element.prototype
//所有元素(HTML XML SVG)的原型

Element.prototype.__proto__ === Node.prototype
//所有节点的原型

Node.prototype.__proto__ === EventTarget.prototype
//DOM事件操作,监听,触发接口的原型

EventTarget.prototype.__proto__ === Object.prototype
//对象的原型

新增节点

  1. 创建一个节点
// 标签节点
let div1 = document.createElement('div')
let style1 = document.createElement('style')
let script1 = document.createElement('script')
// 文本节点
let text1 = document.createTextNode('你好')
// 将文本节点插入到元素中(全覆盖)
div1.appendChild(text1)
div1.innerText = '你好'
div1.textContent = '你好'
// 将在页面中的元素插入到页面中
document.body.appendChild(div1)
div1.appendChild(text1)

注意:

简述DOM中的API

一个节点只能被添加一次,不能被重复使用,除非在拷贝一份

简述DOM中的API

拷贝语法:

let text2 = text1.cloneNode.call(text1,true)

//true表示深拷贝 , false表示浅拷贝

删除节点

div1.parentNode.removeChild(div1)
// 从树中删除节点

div1 = null
// 从内存中删除节点
div1.remove.call(div1)
// 在IE中存在一定兼容问题

改属性

// 修改class
div1.className = 'red' //全覆盖
div1.className += ' blue' 
div1.classList.add('green')
//修改style
div1.style = 'color : green' //全覆盖
div1.style.color = 'green'
div.style.backgroundColor = 'green' //css中为 background-color ,因为js会将 - 识别为减号,所以应将c大写
//修改data-*
div.dataset.x = 'xxx'

读属性

div1.className
div1.style
div1.id
div1.classList

注意点:

简述DOM中的API

在读 标准属性 时,可以使用 getAttribute 获取值(更加精准)


改内容

// 改事件处理函数

div.onclick = function(){
    console.log('hi')
}

/*
div.onclick 默认为 null
将其改写为一个函数fn后
点击div时,会调用fn
此时,fn.call(div,event)
div 会被当做this
event 包含了点击事件的所有详细,例如坐标
*/
//改文本内容

div1.innerText = 'xxx'
div1.textContent = 'xxx'
// 改html内容
div.innerHtml = '<span> hi </span>'
//改标签
div1.appendChild(div2)
// 改parent
newParent.appendChild(div1)

// 查自己
div1
//查parent
div1.parentNode
div1.parentElememt
//查children
div1.childrenNodes
div1.children

简述DOM中的API childNodes 会将空格也打印出来,而children则不会

简述DOM中的API querySelectorAll() 并不会进行实时更新

// 查兄弟(遍历)

let siblings = []
let c = div1.parentElement.children
for (let i = 0; i < c.length; i++){
    if(c[i] !== div1){
        siblings.push.call(siblings,c[i])
    }
}
// 查老大

div.firstChild
// 查老幺

div.lastChild
//查上一个/下一个兄弟
div1.previousSibling //包括文本节点
div1.previousElementSibling //不包括文本节点
div1.nextSibling //包括文本节点
div1.nextElementSibling //不包括文本节点

DOM的跨线程操作

浏览器分为JS引擎与渲染引擎

JS引擎负责操作JS

渲染引擎负责操作页面

当我们使用DOM去操作时,会进行跨线程通信,所以速度会较慢

简述DOM中的API

当我们对已经存在的标签通过DOM进行修改时,浏览器有可能会进行重新渲染

属性同步

当我们对标准属性(如:id、className、title、data-*等)修改时,会同步到页面中,若为非标准属性,则只会停留在JS线程中,不会头部到页面上。

简述DOM中的API

properties与attribute的区别

propertoes对应的是JS中的属性

attribute对应的是页面中的属性

所以,他们不一定相同

而且,property支持字符串,布尔值等类型

但是,attribute只支持字符串

转载自:https://juejin.cn/post/6844904160635142152
评论
请登录