DOM树中的每一个内容都称之为节点,主要包括元素节点,属性节点,文本节点等,本博客主要讲述JavaScript中对DOM树的直接操作,包括对节点的增删,查找。
在[JavaScript:DOM对象]中,我已经讲述了获取节点的方法,即document.querySelector
以及document.querySelectorAll
。但是它们都是直接通过选择器查找指定节点,本博客的查找节点,则是通过节点间的关系来查找。
语法:
子元素.parentNode()
这个函数可以返回父元素的节点,根据树的定义,任何一个子元素都只有一个父亲,否则就不算树结构了,所以DOM树中的任意一个节点,都只有一个父亲。
故此函数的返回值是唯一的。
现在我们有如下结构:
一个父级的ul,内部有四个子级的li,接下来我们尝试使用粉色盒子找父级元素pink.parentNode
:
可以看到,我们确实通过pink.parentNode
找到了其父级元素ul,并将其改为了银色;
那么ul的父亲是谁?
我们观察HTML代码中,ul外层嵌套的是body,那么ul的父亲就是body。在HTML中,由于父子级的嵌套关系十分明显,所以这种方式可以帮助我们快速地锁定父级元素。
语法:
父元素.children
在JavaScript中,其实我们也有父元素.childNodes
这个写法,但是这个写法会得到所有类型的子节点,我们一开始梳理的时候就说明过,元素的节点有非常多种类,但是我们在网页开发中,一般只需要元素节点,而父元素.children
这个写法得到的就是所有的元素节点。
可以看到,两种写法中父元素.children
得到了所有的子节点,而父元素.childNodes
还会有多余的文本text。
此外,由于一个父亲可以有多个孩子,所以返回结果是一个数组的形式,不过是一个伪数组,不能对其增加删除。
语法:
元素.nextElementSibling
元素.previousElementSibling
由于子元素中,其可能在前后都有兄弟,所以兄弟节点的查找也有两个函数。顾名思义nextElementSibling
就是下一个节点,而previousElementSibling
就是上一个节点。
此外,我们还可以对兄弟进行多层递进,比如元素.previousElementSibling.previousElementSibling
就是上上个兄弟。
示例:
追加节点主要分为两种方式:直接在所有子元素的末尾追加,以及插入到某个子元素的前面。
在末尾追加:
语法:
父元素.appendChild(要插入的元素)
示例:
现在我们将原先在末尾的绿色li拿出父级盒子,然后我们再追加:
可以看到,我们将绿色的盒子追加到了父级盒子的末尾,而且原先的绿色盒子消失了。
在指定位置插入:
语法:
父元素.insertBefore(要插入的元素, 被插入的元素)
以上代码,会在被插入的元素前面插入目标元素。
示例:
我们现在将黄色盒子拿出father:
请问如何让其回到原位?
那么就要考虑,是在谁的前面插入,此处要在绿色前面插入,所以插入的代码就是:father.insertBefore(gold, palegreen)
,看看效果:
以上两个追加方式,都有一个问题,那就是追加后,原先的元素会消失,相当于将原先的元素移动到了目标位置。
如果你想保留原来的元素,可以使用克隆的方式,复制一份节点。
语法:
元素.cloneNode(Boolean)
此处的布尔值为true时,会将该元素的后代一起复制,否则只复制该元素。
布尔值为false:
可以看到,我们确实利用克隆,在完成了插入的同时,保留了原先的元素。
但是这个克隆得到的元素,内部没有文字,这是因为我们的参数为false,也就是只克隆这个元素本身,不克隆元素的内容。
布尔值为true:
当布尔值改为true后,克隆得到的元素,就包含元素内部的东西了。
语法:
父元素.removeChild(要删除的元素)
示例:
1.解析(Parser)HTML,生成DOM树(DOM Tree)
2.同时解析(Parser) CSS,生成样式规则 (Style Rules)
3.根据DOM树和样式规则,生成渲染树(Render Tree)
4.进行布局 Layout(回流/重排)
5.根据生成的渲染树,得到节点的几何信息(位置,大小)
6.进行绘制 Painting(重绘): 根据计算和获取的信息进行整个页面的绘制
7.Display: 展示在页面上
当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为 回流。
由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、outline等), 称为重绘。
会导致回流(重排)的操作:
页面的首次刷新
浏览器的窗口大小发生改变
元素的大小或位置发生改变
改变字体的大小
内容的变化(如:input框的输入,图片的大小)
激活css伪类 (如::hover)
脚本操作DOM(添加或者删除可见的DOM元素)
简单理解影响到布局了,就会有回流