问题描述
-
在执行之前检查DOM更新是否真的需要。这有利于避免不必要的更新,但我浪费空间来跟踪旧值。
if(oldValue! == newValue){
element.textContent = newValue;
}
-
只要做到这一点。这显然比较简单,但我恐怕会触发重新绘制并无故重新流回。
element.textContent = newValue ;
我正在研究一个小型JavaScript模板引擎,并且我有两种可能的方法来处理模型更改时DOM的更新:
请注意,我也在操纵DOM调用 setAttribute
, addClass
和 removeClass
,再加上 style [prop] = value
。
所以,我的问题是:现代浏览器是否足够聪明, ,并且因此不运行重排或重绘,如果你触摸DOM而没有实际改变任何东西?
使用您可以检测到 DOM
更改。 以下示例可用于查看浏览器是否触发 Dom Changed
事件,基于你想要的。
这里有一个文本('... ')
由jquery和 el.textContent
(不使用jquery)。
$(document).ready(function(){$('#btn1')。click(function(){console.log('text changed - jquery'); $('#a1')。text('text 1'); }); $('#btn2')。click(function(){console.log('text changed - textContent'); $('#a1')[0] .textContent = $('#a1')[0]。 textContent}); $('#btn3')。click(function(){console.log('class changed'); $('#a1')。attr('class','cls'+ Math.floor(Math.random )* 10));});}); var target = $('#a1')[0]; //创建一个观察者instancevar observer = new MutationObserver(function(mutations){var changed = false; mutations.forEach (function(mutation){//你可以在这里查看实际的变化}); console.log('Dom Changed');}); //配置观察者:var config = {attributes:true,childList:true, characterData:true}; //传入目标节点以及observer optionsobserver.observe(target,config);
.cls1 {border:1px solid red;}。cls2 {border:1px solid pink;}。cls3 {border:1px solid cyan;}。cls4 {border: cls5 {border:1px solid orange;}。cls5 {border:1px solid dark;}。cls8 {border:1px solid black;}。cls8 {border:1px solid yellow;}。cls9 {border: 1px固体蓝色;}。cls10 {border:1px solid green;}
< script src =https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js>< / script>< div id =a1class = cls1>文字1< / div>< button id =btn1>更改文字 - jquery(保留原文)< / button>< br />< button id =btn2>更改文本 - textContent(保留原文)< / button>< br />< button id =btn3>更改类别(实际更改)< /按钮>
$在Chrome 55中,只有 setAttribute() code>和jQuery text()
触发了 Dom Change
事件。
在Firefox 50中,所有内容都触发了 Dom Change
事件。
在Edge 38中,所有内容都触发了 Dom Change
事件。
I am working on a small JavaScript template engine, and I have two possible approaches for dealing with updates to the DOM when the model changes:
Check if the DOM update is really needed before doing it. This has the benefit of not risking unnecessary updates, but I am wasting space on keeping track of old values.
if (oldValue !== newValue) {
element.textContent = newValue;
}
Just do it. This is obviously simpler, but I am afraid that I will be triggering repaints and reflows for no reason.
element.textContent = newValue;
Note that I am also manipulating the DOM by calling setAttribute
, addClass
and removeClass
, plus setting style[prop] = value
.
So, my question is: Are modern browsers smart enough to notice that nothing actually changed, and therefore not run reflow or repaint, if you touch the DOM without actually changing anything?
解决方案 Using the MutationObserver
api you can detect DOM
changes.
Here is an example you can use to see if a browser triggers the Dom Changed
event, based on what you want.
You have here both a text('...')
by jquery and an el.textContent
(that doesn't use jquery).
$(document).ready(function() {
$('#btn1').click(function() {
console.log('text changed - jquery');
$('#a1').text('text 1');
});
$('#btn2').click(function() {
console.log('text changed - textContent');
$('#a1')[0].textContent = $('#a1')[0].textContent
});
$('#btn3').click(function() {
console.log('class changed');
$('#a1').attr('class', 'cls' + Math.floor(Math.random() * 10));
});
});
var target = $('#a1')[0];
// create an observer instance
var observer = new MutationObserver(function(mutations) {
var changed = false;
mutations.forEach(function(mutation) {
// You can check the actual changes here
});
console.log('Dom Changed');
});
// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true };
// pass in the target node, as well as the observer options
observer.observe(target, config);
.cls1 {
border: 1px solid red;
}
.cls2 {
border: 1px solid pink;
}
.cls3 {
border: 1px solid cyan;
}
.cls4 {
border: 1px solid darkgreen;
}
.cls5 {
border: 1px solid orange;
}
.cls6 {
border: 1px solid darkred;
}
.cls7 {
border: 1px solid black;
}
.cls8 {
border: 1px solid yellow;
}
.cls9 {
border: 1px solid blue;
}
.cls10 {
border: 1px solid green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a1" class="cls1">text 1</div>
<button id="btn1">Change text - jquery (keep original)</button><br />
<button id="btn2">Change text - textContent (keep original)</button><br />
<button id="btn3">Change class (real change)</button>
- In Chrome 55, only
setAttribute()
and jQuery text()
triggered the Dom Change
event. - In Firefox 50, everything triggered the
Dom Change
event. - In Edge 38, everything triggered the
Dom Change
event.
这篇关于即使没有任何变化,触摸DOM触发回流和重绘吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!