有没有一种方法可以检测到元素的父元素何时发生更改(即,当元素从null
更改为!null
时,即元素最初添加到DOM时),使用{{ 1}}?我找不到任何文档说明如何实现此目标。
我正在以编程方式使用MutationObserver
创建元素。我从函数返回创建的元素,但想从函数内部创建一个侦听器,以在元素最终添加到DOM时做出反应,而又不知道 where 或< em>哪个父对象。
老实说,我不太确定该怎么说。
document.createElement()
我看不出要理解它有什么难之处或为什么要关闭它。
答案 0 :(得分:1)
您可以收听DOMNodeInserted
事件并比较元素ID。
通知: 该事件被标记为已取消,并且可能会在不久的将来停止在现代浏览器中运行 未来。
let container = document.getElementById('container');
let button = document.getElementById('button');
document.body.addEventListener('DOMNodeInserted', function(event) {
if (event.originalTarget.id == button.id) {
console.log('Parent changed to: ' + event.originalTarget.parentElement.id);
}
});
button.addEventListener('click', function(event) {
container.appendChild(button);
});
#container {
width: 140px;
height: 24px;
margin: 10px;
border: 2px dashed #c0a;
}
<div id="container"></div>
<button id="button">append to container</button>
答案 1 :(得分:1)
一种简单而精致的方法是猴子补丁Node.prototype.appendChild
(必要时还有Element.prototype.append
,Element.prototype.insertAdjacentElement
和Node.prototype.insertBefore
)来监视何时将元素添加到DOM:
const elementsToWatch = new Set();
const { appendChild } = Node.prototype;
Node.prototype.appendChild = function(childToAppend) {
if (elementsToWatch.has(childToAppend)) {
console.log('Watched child appended!');
elementsToWatch.delete(childToAppend);
}
return appendChild.call(this, childToAppend);
};
button.addEventListener('click', () => {
console.log('Element created...');
const div = document.createElement('div');
elementsToWatch.add(div);
setTimeout(() => {
console.log('About to append element...');
container.appendChild(div);
}, 1000);
});
<button id="button">Append something after 1000ms</button>
<div id="container"></div>
但是,将内置原型静音通常不是一个好主意。
另一种选择是对整个文档使用MutationObserver,但这很可能会导致大量频繁出现突变的大页面的激活回调,这可能是不希望的:
const elementsToWatch = [];
new MutationObserver(() => {
// instead of the below, another option is to iterate over elements
// observed by the MutationObserver
// which could be more efficient, depending on how often
// other elements are added to the page
const root = document.documentElement; // returns the <html> element
const indexOfElementThatWasJustAdded = elementsToWatch.findIndex(
elm => root.contains(elm)
);
// instead of the above, could also use `elm.isConnected()` on newer browsers
// if an appended node, if it has a parent,
// will always be in the DOM,
// instead of `root.contains(elm)`, can use `elm.parentElement`
if (indexOfElementThatWasJustAdded === -1) {
return;
}
elementsToWatch.splice(indexOfElementThatWasJustAdded, 1);
console.log('Observed an appended element!');
}).observe(document.body, { childList: true, subtree: true });
button.addEventListener('click', () => {
console.log('Element created...');
const div = document.createElement('div');
div.textContent = 'foo';
elementsToWatch.push(div);
setTimeout(() => {
console.log('About to append element...');
container.appendChild(div);
}, 1000);
});
<button id="button">Append something after 1000ms</button>
<div id="container"></div>