我有Chrome扩展程序,我想等到元素加载后再将内容注入页面。
我试图按下按钮:
myButton = document.createElement('button');
myButton.class = 'mybutton';
document.querySelector('.element_id').appendChild(myButton)
我在内容脚本的顶部有这个。它过去工作得很好,但后来它停止工作。显示的错误是:
Uncaught TypeError: Cannot read property 'appendChild' of null
为了等待加载类ID .element_id
的元素,我尝试使用MutationObserver
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (!mutation.addedNodes) return
for (var i = 0; i < mutation.addedNodes.length; i++) {
if (mutation.addedNodes[i].parentNode == document.querySelector('#outer-container')) {
myButton = document.createElement('button');
myButton.class = 'mybutton';
document.querySelector('.element_id').appendChild(myButton)
}
var node = mutation.addedNodes[i]
}
})
})
observer.observe(document.body, {
childList: true
, subtree: true
, attributes: false
, characterData: false
})
当我使用变异观察者时,页面会加载一个名为outer-container
的外部div元素,而我无法直接比较类.element_id
。类.element_id
将多个层嵌套到外部div中。
但是,上面的方法不起作用,我仍然收到了null属性错误。
在注入之前是否有更好的方法等待加载某个元素(加载异步)?
答案 0 :(得分:1)
在观察更改时,不要忘记添加childList
和subtree
属性。
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (!mutation.addedNodes) {
return;
}
for (var i = 0; i < mutation.addedNodes.length; i++) {
if (mutation.addedNodes[i].classList.contains("element_id")) {
// Your logic here
}
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
答案 1 :(得分:1)
插入DOM可能会使添加的节点中的元素更深。
例如,可以将其插入DOM:
<div class="container">
<div class="element_id">...</div>
...
</div>
在这种情况下,添加的节点列表将只包含.container
节点。
变异不会列出添加的所有内容,您有责任通过添加的节点递归挖掘添加的片段。
使用mutation-summary
library可以帮助您避免此类问题。
var observer = new MutationSummary({
rootNode: document.body,
callback: function(summaries) {
summaries.forEach(function(summary) {
summary.added.forEach(function(idElement) {
/* ... */
idElement.appendChild(myButton);
});
});
},
queries: [{element: ".element_id"}]
});
如果您不想使用图书馆,可以尝试在querySelector
上致电querySelectorAll
或addedNodes[i]
。