一道简单的题目,
目标是完成函数,做到将一个元素内的所有子元素倒序排列。因为是需要连同标签一起改变,所以第一时间想到了outerHTML这个属性
outerHTML
属性获取描述元素(包括其后代)的序列化 HTML 片段。它也可以设置为用从给定字符串解析的节点替换元素。
function reverse()
{
let box= document.getElementById("box");
let child=box.children;
let oldChild=[...child];
for(let i=0;i<child.length;i++)
{
child[i].outerHTML=oldChild[child.length-1-i].outerHTML;
}
}
childNodes | 获取所有子节点 | 不推荐使用,如果有空格,会作为文本节点获取到 |
children | 获取所有子节点 | 推荐使用(? |
这里我将box的子元素数组复制一份,然后倒着将其outerHTML内容赋给原数组。需要注意复制数组的时候不能简单的赋值,要分清楚深浅拷贝,否则它们是引用了同一个目标(box的children),目标内容一旦改动两个数组都会一起变,所以倒叙过半就会出错。
这个方法很简单很直接,在应对少量数据的时候也能完美完成任务。现在,我试着用js生成一万个span元素,然后对其进行倒序。
就像这样
<style>
#box {
width: 1500px;
display: flex;
flex-wrap: wrap;
}
span{
padding: 0 4px;
box-sizing: border-box;
border: 1px solid #ccc;
}
</style>
function create()
{
let box= document.getElementById("box");
for(let i=0;i<10000;i++)
{
let s = document.createElement('span');
s.innerHTML=i;
box.appendChild(s);
}
}
点击按钮,发现成功倒序排列了。但老师指出,很多有关效率的问题我并没有考虑到,比如
重绘和重排的知识。
我刚才的代码是相当花时间的,无法做到点击按钮后立刻得到结果。而要提高效率,就要注重两个方面,渲染的效率和脚本的效率。渲染效率,就涉及到了重绘和重排。
当DOM的变化影响了元素的几何信息(元素的的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。
重排也叫回流,简单的说就是重新生成布局,重新排列元素。
重排的代价是高昂的,会破坏用户体验,并且让UI展示非常迟缓。通过减少重排的负面影响来提高用户体验的最简单方式就是尽可能的减少重排次数,重排范围。
在动态添加大量DOM时,其中很重要的一个优化重排方法便是使用DocumentFragment。