// 调用示例
// observeElement('.tooltip.tooltip--memo:not(.fn__none)', ({element, mutationsList, stop})=>{
// console.log([element?.outerHTML,mutationsList, stop]);
// });
async function observeElement(selector, callback, options, observedEl, delay = 100) {
let observer, selectorFn = selector;
let isStopped = false;
let lastElementExists = false; // 记录上一次元素是否存在
// 转换选择器为函数
if (typeof selector !== 'function') {
selectorFn = () => {
if (selector?.nodeType === 1) return selector;
return typeof selector === 'string' ? document.querySelector(selector) : null;
};
}
const stop = () => {
isStopped = true;
observer?.disconnect();
};
// 初始检查
const initialElement = selectorFn();
lastElementExists = !!initialElement;
if (initialElement && typeof callback === 'function') {
callback({ element: initialElement, mutationsList: null, stop });
if (isStopped) return;
}
if (isStopped) return;
// 核心优化:仅在元素存在状态变化时触发回调
let ticking = false;
observer = new MutationObserver((mutationsList) => {
if (!ticking) {
ticking = true;
requestAnimationFrame(() => {
const currentElement = selectorFn();
const currentExists = !!currentElement;
// 状态变化时才触发
if (currentExists !== lastElementExists) {
if (currentExists && typeof callback === 'function') {
callback({
element: currentElement,
mutationsList: currentExists ? mutationsList : [],
stop
});
}
lastElementExists = currentExists;
}
ticking = false;
});
}
});
if (isStopped) return;
// 优化监听范围:只监听必要的变化
if (typeof observedEl === 'string') {
observedEl = await whenElementExist(observedEl);
if (isStopped) return;
}
observer.observe(observedEl || document.body, options || {childList: true, subtree: true});
}
