可用來監聽window對象的變化javascript
// 基準大小 const baseSize = 41.4; // 設置 rem 函數 function setRem(width) { // 當前頁面寬度相對於 414 寬的縮放比例,可根據本身須要修改。 const scale = width / 414; // 設置頁面根節點字體大小 document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + 'px'; } window.addEventListener('resize', debounce(setRem));
須要注意的是resize是高頻事件,可以使用debounce
防止屢次觸發css
MutationObserver(callback)
爲構造函數,可用於實例化監聽DOM節點變化的觀察器實例對象擁有三個方法:html
observe(element, options)
開始觀察節點,發生變化時觸發回調(先放到消息隊列裏)disconnect()
中止觀察器,直到再次調用observe()
takeRecords()
將消息隊列裏未處理的變化通知所有刪除並返回詳細參考MDN: MutationObserver
<!DOCTYPE html> <html> <head> <title>Mutation Observer</title> <style type="text/css"> .box { width: 100px; height: 100px; background-color: red; } .child{ width: 50px; height: 50px; background-color: blue; } </style> </head> <body> <div class="box"> <div class="child"></div> </div> <script type="text/javascript"> const { log } = console; let MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; // box觀察器的回調 let boxCallback = (mutationList) => { log('box callback is called'); for (let mutation of mutationList) { log(mutation); log(mutation.target); log('oldValue: ' + mutation.oldValue); log(''); } }; // 用於text觀察器的回調 let textCallback = (mutationList) => { log('text callback is called'); for (let mutation of mutationList) { log(mutation); log(mutation.target); log('oldValue: ' + mutation.oldValue); log(''); } }; // 用於處理takeRecords()接收到的變化 let takeRecordsCallback = (mutationList) => { log('take records callback is called'); for (let mutation of mutationList) { log(mutation); log(mutation.target); log('oldValue: ' + mutation.oldValue); log(''); } }; let observer_box = new MutationObserver(boxCallback); // 此回調是異步的 let observer_text = new MutationObserver(textCallback); let box = document.querySelector('.box'); observer_box.observe(box, { childList: true, attributes: true, subtree: true, attributeFilter: ['style'], attributeOldValue: true // 開啓後oldValue會記錄變化,初始爲null }); box.style.width = '200px'; // MutationRecord {type: "attributes", oldValue: null, ...} box.style.width = '400px'; // MutationRecord {type: "attributes", oldValue: "width: 200px;", ...} box.appendChild(document.createElement('div')); // MutationRecord {type: "childList", oldValue: null, ...} let child = document.querySelector('.child'); child.style.width = '100px'; // MutationRecord {type: "attributes", oldValue: null, ...} child.style.width = '200px'; // MutationRecord {type: "attributes", oldValue: "width: 100px;", ...} var mutations = observer_box.takeRecords(); // 將上面的MutationRecord都獲取了,因爲callback都是異步的,故上面的的callback未執行 if (mutations) { takeRecordsCallback(mutations); } // log('observer_box will disconnect') // observer_box.disconnect(); // 放入消息隊列 setTimeout(() => { log('observer_box will disconnect') observer_box.disconnect(); }, 0); let textNode = document.createTextNode('1'); child.appendChild(textNode); // MutationRecord {type: "childList", target: div.child, ...} // characterData須要用在text或comment元素纔有效果 observer_text.observe(textNode, { characterData: true, characterDataOldValue: true // oldValue初始爲text的值 }); textNode.appendData('2'); // MutationRecord {type: "characterData", target: text, oldValue: "1"} textNode.appendData('3'); // MutationRecord {type: "characterData", target: text, oldValue: "12"} </script> </body> </html>
須要注意的是:java
MutationObserver
接受的callback執行是異步的,元素更變通常是同步代碼,更變後callback會放入消息queue,等待當前一輪事件循環的結束纔會執行takeRecords()
不是異步的,故能夠取到當前在消息queue的元素變化characterData
參數只有在元素是text
或comment
類型時纔有效果