本帖最后由 庶民 于 2023-6-13 16:26 编辑
给一个我自己写的函数,用于监听查找的元素是否存在,页面渲染完出现后则操作后续步骤:
function getElement(parent, selector, timeout = 0) {
return new Promise(resolve => {
let result = parent.querySelector(selector);
if (result) return resolve(result);
let timer;
const mutationObserver = window.MutationObserver || window.WebkitMutationObserver || window.MozMutationObserver;
if (mutationObserver) {
const observer = new mutationObserver(mutations => {
for (let mutation of mutations) {
for (let addedNode of mutation.addedNodes) {
if (addedNode instanceof Element) {
result = addedNode.matches(selector) ? addedNode : addedNode.querySelector(selector);
if (result) {
observer.disconnect();
timer && clearTimeout(timer);
return resolve(result);
}
}
}
}
});
observer.observe(parent, {
childList: true,
subtree: true
});
if (timeout > 0) {
timer = setTimeout(() => {
observer.disconnect();
return resolve(null);
}, timeout);
}
} else {
const listener = e => {
if (e.target instanceof Element) {
result = e.target.matches(selector) ? e.target : e.target.querySelector(selector);
if (result) {
parent.removeEventListener('DOMNodeInserted', listener, true);
timer && clearTimeout(timer);
return resolve(result);
}
}
};
parent.addEventListener('DOMNodeInserted', listener, true);
if (timeout > 0) {
timer = setTimeout(() => {
parent.removeEventListener('DOMNodeInserted', listener, true);
return resolve(null);
}, timeout);
}
}
});
}
原理是首先用querySelector获取元素,获取不到时用MutationObserver监听插入节点,直到获取到所需元素,页面不支持MutationObserver时改用DOMNodeInserted实现,获取到元素后自动移除相关监听事件。代码看不懂也没关系,直接复制过去用就行了。第1个参数是父节点,第2个参数同querySelector,第3个参数是可选的超时时间(毫秒),设定最长监听时间以防止长时间等待,默认0不设超时。返回类型为Promise,需要用.then链式调用,或者async/await实现类似同步调用的效果,以下是调用示例(推荐后一种方式):
function example1() {
getElement(document, '#test').then(element => {
//...
});
}
async function example2() {
const element = await getElement(document, '#test');
//...
}
补充其他提到的:
好像matches有兼容性问题,如果你的浏览器不支持,在代码前加一句:
Element.prototype.matches = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.mozMatchesSelector;
|