目录
方法1:方法一:隐藏ul后,给ul添加节点,添加完成后再将ul显示
方法二:创建文档碎片,将所有li先放在文档碎片中,等都放进去以后,再将文档碎片放在ul中
方法三:将ul拷贝一份,将所有li放在拷贝中,等都放进去以后,使用拷贝替换掉ul
一、批量设置样式
封装一个批量设置样式的函数
function setStyle(ele,styleObj){
for(var key in styleObj){
ele.style[key]=style[key]}}
二、回流
- 解析html生成DOM树,解析CSS,生成cssdom树,将dom树和cssdom树结合,生成渲染树。
- 根据渲染树,加上节点信息和图形处理,最后在页面显示。
- 回流:当渲染树中节点信息发生大小,边距等问题,需要重新计算各节点,和CSS具体的大小和位置。
- 容易造成回流的操作:
-
布局流相关操作
-
盒模型的相关操作会触发重新布局
-
定位相关操作会触发重新布局
-
浮动相关操作会触发重新布局
-
节点操作:改变节点的结构或其中的文本结构会触发重新布局。
-
offsetTop offsetLeft offsetWidth offsetHeight scrollTop scrollLeft scrollWidth scrollHeight clientTop clientLeft clientWidth clientHeight getComputedStyle
-
css
-
width height padding border margin position top left bottom right float clear text-align vertical-align line-height font-weight font-size font-family overflow white-space
三、重绘
- 重绘:当节点的部分属性发生变化,但不影响布局,只需要重新计算节点在屏幕中的绝对位置并渲染的过程,就叫重绘。比如:改变元素的背景颜色、字体颜色等操作会造成重绘。
- 回流的过程在重绘的过程前面,所以回流一定会重绘,但重绘不一定会引起回流。
- 容易造成重绘操作的css:color border-style border-radius text-decoration box-shadow outline background
四、优化
回流和重绘都要避免回流。
一、合并样式修改
减少回流次数,如果要给一个节点操作多个CSS属性,每一个都造成回流,尽量将多次操作合并成一个。
var oDiv = document.querySelector('.box');
oDiv.style.padding = '5px';
oDiv.style.border = '1px solid #000';
oDiv.style.margin = '5px';
将css三个属性合并在一起。
方法一:使用style的cssText
oDiv.style.cssText = 'padding:5px; border:1px solid #000; margin:5px;';
方法二:将他们定义给一个类名,给标签加类名:
<style>
.pbm{
padding:5px;
border:1px solid #000;
margin:5px;
}
</style>
<script>
var oDiv = document.querySelector('.box');
oDiv.classList.add('pbm');
</script>
二、批量操作DOM
当对DOM有多次操作的时候,需要使用一些特殊处理减少触发回流,其实就是对DOM的多次操作,在脱离标准流后,对元素进行多次操作,不会触发回流,等操作完成后,再将元素放回标准流。
方法1:方法一:隐藏ul后,给ul添加节点,添加完成后再将ul显示
在隐藏ul和显示ul的时候,触发了两次回流,给ul添加每个li的时候没有触发回流。
方法二:创建文档碎片,将所有li先放在文档碎片中,等都放进去以后,再将文档碎片放在ul中
文档碎片就是一个虚拟的DOM节点。对文档碎片操作不会造成回流。
方法三:将ul拷贝一份,将所有li放在拷贝中,等都放进去以后,使用拷贝替换掉ul
三、避免多次布局
回到顶部操作:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.goBack{
position: fixed;
bottom: 0px;
right: 0px;
}
body{
width: 10px;
}
</style>
<body>
行路难.其一
金樽清酒斗十千,玉盘珍羞直万钱。
停杯投箸不能食,拔剑四顾心茫然。
欲渡黄河冰塞川,将登太行雪满山。
闲来垂钓碧溪上,忽复乘舟梦日边。
行路难,行路难,多歧路,今安在?
长风破浪会有时,直挂云帆济沧海。
行路难.其二
大道如青天,我独不得出。
羞逐长安社中儿,赤鸡白雉赌梨栗。
弹剑作歌奏苦声,曳裾王门不称情。
淮阴市井笑韩信,汉朝公卿忌贾生。
君不见昔时燕家重郭隗,拥篲折节无嫌猜。
剧辛、乐毅感恩分,输肝剖胆效英才。
昭王白骨萦蔓草,谁人更扫黄金台?
行路难,归去来!
行路难.其三
有耳莫洗颍川水,有口莫食首阳蕨。
含光混世贵无名,何用孤高比云月?
吾观自古贤达人,功成不退皆殒身。
子胥既弃吴江上,屈原终投湘水滨。
陆机雄才岂自保?李斯税驾苦不早。
华亭鹤唳讵可闻?上蔡苍鹰何足道?
君不见吴中张翰称达生,秋风忽忆江东行。
且乐生前一杯酒,何须身后千载名?
<button class="goBack">
胡来
</button>
</body>
<script>
var goBack=document.querySelector('.goBack')
console.log(goBack)
goBack.onclick = function(){
var ww= setInterval(function(){
var t = document.documentElement.scrollTop || document.body.scrollTop;
t -= 10;
document.documentElement.scrollTop = document.body.scrollTop = t;
if(t<0){
clearInterval(ww)
}
},20)
}
</script>
</html>
每隔20秒都会重新获取滚动过的距离,每次都会触发回流,优化代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.goBack {
position: fixed;
bottom: 0px;
right: 0px;
}
body {
width: 10px;
}
</style>
<body>
行路难.其一
金樽清酒斗十千,玉盘珍羞直万钱。
停杯投箸不能食,拔剑四顾心茫然。
欲渡黄河冰塞川,将登太行雪满山。
闲来垂钓碧溪上,忽复乘舟梦日边。
行路难,行路难,多歧路,今安在?
长风破浪会有时,直挂云帆济沧海。
行路难.其二
大道如青天,我独不得出。
羞逐长安社中儿,赤鸡白雉赌梨栗。
弹剑作歌奏苦声,曳裾王门不称情。
淮阴市井笑韩信,汉朝公卿忌贾生。
君不见昔时燕家重郭隗,拥篲折节无嫌猜。
剧辛、乐毅感恩分,输肝剖胆效英才。
昭王白骨萦蔓草,谁人更扫黄金台?
行路难,归去来!
行路难.其三
有耳莫洗颍川水,有口莫食首阳蕨。
含光混世贵无名,何用孤高比云月?
吾观自古贤达人,功成不退皆殒身。
子胥既弃吴江上,屈原终投湘水滨。
陆机雄才岂自保?李斯税驾苦不早。
华亭鹤唳讵可闻?上蔡苍鹰何足道?
君不见吴中张翰称达生,秋风忽忆江东行。
且乐生前一杯酒,何须身后千载名?
<button class="goBack">
胡来
</button>
</body>
<script>
var goBack = document.querySelector('.goBack')
goBack.onclick = function () {
var t = document.documentElement.scrollTop || document.body.scrollTop;
var ww = setInterval(function () {
t -= 10;
document.documentElement.scrollTop = document.body.scrollTop = t;
if (t < 0) {
clearInterval(ww)
}
}, 20)
}
</script>
</html>
仅获取一次,每次都让数字递增,避免每次都获取滚动过的距离。
注意:对于页面比较复杂的动画,尽量将元素设置为绝对定位,操作元素定位属性,这样只有这一个元素会回流,如果不是定位的话,容易引起父元素和子元素的回流。
四、修改批量设置函数样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<div >
学校的教室财产管理员和暖气管理员,在商中工作36年,今年2月退休,7月底那天,突发心脏病不幸去世。近一些时日,我常常想起他。
选正是学校后勤上的一名干事,我上世纪80年代在商中上学时就认识他。那时,我们班的玻璃烂了,选正老师就用右臂夹着大块玻璃,左手拿着玻璃刀、尺子和玻璃泥等,趁课间很快就将破烂的玻璃换掉,安上新玻璃。他换玻璃很细致,先量窗框,再裁玻璃,然后将玻璃泥揉成条状,然后装上一寸不多一寸不
</div>
</body>
<script>
function setStyle(ele, styleObj) {
var cssText = ''
for(var key in styleObj) {
var cssProp = key
for(var a = 0; a < cssProp.length; a++) {
var charCode = cssProp.charCodeAt(a)
if(charCode >= 65 && charCode <= 90) {
cssProp = cssProp.slice(0, a) + '-' + cssProp[a].toLowerCase() + cssProp.slice(a+1)
}
}
cssText += cssProp + ':' + styleObj[key] + ';'
}
ele.style.cssText = cssText
}
var div=document.querySelector('div')
setStyle(div,{
width:'200px',
height:'400px',
border:'10px solid green',
backgroundColor:'purple'
})
</script>
</html>