浏览器提供了 5 种 Observer 来监听这些变动:
MutationObserver、IntersectionObserver、PerformanceObserver、ResizeObserver、ReportingObserver
浏览器渲染过程中, 会对这些监听事件调用
callback一般会触发两次。一次是目标元素刚刚进入视口(开始可见),另一次是完全离开视口(开始不可见)
function intersection(entries) {
entries.forEach((entry) => {
if (entry.isIntersecting) {
var targetNode = entry.target;
// do sth
}
})
}
var intersectionObserver = new IntersectionObserver(intersectionCallback, options);
intersectionObserver.observe(targetNode);
var mutationObserver = new MutationObserver(mutationCallback, options);
mutationObserver.observe(targetNode);
let Options = {
childList: bool,
attributes: bool,
characterData: bool,
subtree: bool,
attributeFilter: array,
attributeOldValue: bool,
characterDataOldValue: bool,
}
const mutationObserver = new MutationObserver((mutations) => {
console.log('trigged')
for (let mutation of mutations) {
switch (mutation.type) {
case 'childList': break;
case 'attributes': break;
}
}
});
observer.observe(targetNode, Options);
function callback (mutationList, observer) {
mutationList.forEach((mutation) => {
switch (mutation.type) {
case 'childList':
/* 从树上添加或移除一个或更多的子节点;参见 mutation.addedNodes 与
mutation.removedNodes */
console.log(mutation)
break
case 'attributes':
/* mutation.target 中某节点的一个属性值被更改;该属性名称在 mutation.attributeName 中,
该属性之前的值为 mutation.oldValue */
console.log('attributes')
break
}
})
}
let targetNode = document.querySelector('#sidebar_shortcut') // 获取监听 DOM 对象
let observerOptions = {
childList: true, // 观察该元素的子元素新增或者删除
attributes: true, // 观察属性变动
subtree: true, //该元素的所有子元素新增或者删除
characterData: true, // 监听text或者comment变化
attributeOldValue: true, //属性原始值
characterDataOldValue: true
}
let observer = new MutationObserver(callback)
observer.observe(targetNode, observerOptions)
// 操作
let dom = document.createElement('li')
dom.innerHTML = '测试';
setTimeout(() => {
targetNode.appendChild(dom) // 触发 childList
}, 1000)
setTimeout(() => {
targetNode.style.color = 'red' // 触发 attributes
}, 2000)