一、mutationobserver基礎及用途
1、mutationobserver是什麼?
var observer = new MutationObserver(callback);
mutationobserver指的是監測DOM變化的接口。可以用來監測DOM的子節點、屬性和文本變化等等。下面是一個基本的示例:
var target = document.querySelector('#some-id');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
observer.observe(target, { attributes: true, childList: true, characterData: true });
2、mutationobserver的callback
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
使用mutationobserver需要傳入一個callback函數,當觀察到指定節點的變化時就會回調該函數。該函數的參數是一個MutationRecord對象的數組,MutationRecord對象包含了一些信息,比如打變化的類型、目標節點以及節點的舊值和新值等等,開發者可以根據自己的需求對這些信息做出相應的處理。
3、mutationobserver的用途
mutationobserver在實際開發中有很多用途,比如實時更新某個組件的狀態、監測某個元素的變化、自動設置某個元素的高度等等,可以大大提高開發效率。下面是一些應用實例:
(1)監測某個元素的變化
var targetNode = document.getElementById('target');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(targetNode, config);
(2)實時更新某個組件的狀態
var targetNode = document.getElementById('target');
var observer = new MutationObserver(function(mutations) {
var statusNode = document.getElementById('status');
statusNode.innerHTML = '狀態已更新';
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(targetNode, config);
(3)自動設置某個元素的高度
var targetNode = document.getElementById('target');
var observer = new MutationObserver(function(mutations) {
var heightNode = document.getElementById('height');
heightNode.innerHTML = targetNode.offsetHeight;
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(targetNode, config);
二、mutationobserver常見問題
1、mutationobserver與setTimeout的區別
mutationobserver和setTimeout都可以用來實現實時監測DOM的變化,區別是setTimeout是不停地輪詢DOM結構,而mutationobserver則只會在DOM結構發生變化後才會被觸發。setTimeout的缺點是會佔用一定的CPU資源,同時也可能會導致頁面性能下降。因此,在實現類似功能時更推薦使用mutationobserver。
2、mutationobserver的兼容性
mutationobserver是HTML5的新特性,目前主流瀏覽器均支持,IE11及以上版本也已經支持,但是低於IE11的版本不支持。因此,在兼容性上需要做出一些特別的處理。
3、mutationobserver的性能優化
在使用mutationobserver時一定要注意性能問題,因為如果DOM結構發生變化比較頻繁的話,mutationobserver就會在較短的時間內被頻繁觸發,導致性能下降。因此,開發者需要注意以下幾點:
(1)監測儘可能少的節點,因為監測節點越多,觸發mutationobserver的頻率就越高。
(2)在設置observer.observe()時,盡量避免使用默認的配置,因為默認配置下會監測DOM變化的所有屬性。所以只需要監測需要的節點即可。
(3)合理選擇callback函數中的處理方式,避免無效操作,提高代碼效率。
三、mutationobserver實際應用
1、監測某個元素的變化並更新另一個元素
<div id="target">I love javascript</div>
<div id="result"></div>
<script>
var targetNode = document.getElementById('target');
var resultNode = document.getElementById('result');
var observer = new MutationObserver(function(mutations) {
resultNode.innerHTML = targetNode.innerHTML;
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(targetNode, config);
</script>
2、自動設置某個元素的高度
<div id="target">I love javascript</div>
<div id="height"></div>
<script>
var targetNode = document.getElementById('target');
var heightNode = document.getElementById('height');
var observer = new MutationObserver(function(mutations) {
heightNode.innerHTML = targetNode.offsetHeight;
});
var config = { attributes: false, childList: true, characterData: false };
observer.observe(targetNode, config);
</script>
3、實時更新某個組件的狀態
<div id="target">I love javascript</div>
<div id="status"></div>
<script>
var targetNode = document.getElementById('target');
var statusNode = document.getElementById('status');
var observer = new MutationObserver(function(mutations) {
statusNode.innerHTML = '狀態已更新';
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(targetNode, config);
</script>
四、如何使用mutationobserver實現數據雙向綁定
1、數據雙向綁定是什麼?
數據雙向綁定是指當一個模型(Model)的數據發生變化時,視圖(View)會做出相應的改變;反之,當用戶在視圖上進行操作時,模型中的數據也會跟着改變。
2、如何使用mutationobserver實現數據雙向綁定?
在實現數據雙向綁定時,可以使用mutationobserver來監測數據變化,實現視圖的自動更新。具體實現方法如下:
<input type="text" id="input">
<p id="result"></p>
<script>
// 監測input的變化
var input = document.getElementById('input');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'attributes') {
document.getElementById('result').innerHTML = input.value;
}
});
});
observer.observe(input, { attributes: true });
// 監測result的變化
var result = document.getElementById('result');
result.addEventListener('input', function() {
input.value = result.innerHTML;
observer.disconnect();
// 觸發一次變化事件,通知數據更新
var e = document.createEvent('HTMLEvents');
e.initEvent('change', true, true);
input.dispatchEvent(e);
observer.observe(input, { attributes: true });
});
</script>
實現數據雙向綁定需要注意以下幾點:
(1)需要在監測變化時進行判斷,避免死循環。
(2)需要在DOM節點發生變化時通過觸發一次change事件通知數據進行更新。
(3)在input與result的相互監測時,需要先取消mutatiionobserver的監測,然後再重新開始新的監測。
五、mutationobserver的局限性
mutationobserver雖然強大,但是也有一些局限性,需要注意。
1、mutationobserver的無法監聽CSS的變化。比如改變元素的寬度、高度、位置等屬性,都無法被mutationobserver檢測到。但是可以通過監聽resize或scroll事件的方式來實現。
2、無法檢測到通過cloneNode()操作插入的節點,節點需要完全重新渲染才能被mutationobserver檢測到。
3、無法檢測到對Text節點的修改,因為Text節點的nodeValue屬性是一個字符串,而不是一個DOM元素。
4、無法檢測到通過innerHTML進行賦值的變化,因為這種方式是直接對DOM節點進行賦值,而不是通過DOM操作進行的。
六、總結
mutationobserver作為一種強大的DOM變化監測方式,在實際開發中有着廣泛的應用。通過對它的基礎、常見問題、實際應用以及局限性等方面進行探究,我們可以更好地了解它的使用方法和注意事項,從而更好地應用它,提高開發效率。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/185811.html