我想检测是否从自定义元素添加(或删除)元素。例如,请考虑以下自定义元素
<x-foo>
<div></div>
<div></div>
<div></div>
</x-foo>
现在我可以简单地添加一个元素
document.querySelector('x-foo').appendChild(document.createElement('div'));
有没有例如生命周期回调方法(就像属性更改一样)来检测这个?
答案 0 :(得分:2)
您可以使用element.addEventListener('DOMNodeInserted', function(){})
和element.attachEvent("onpropertychange", function(){})
但不能在所有浏览器上使用..
答案 1 :(得分:1)
超酷的是,您可以使用css动画收听插入内容。只需添加一个具有有限持续时间的难以察觉的css动画,然后听取它的开始。这样做,你不会在元素上监听所有DOMNodeInserted事件(甚至更糟糕的是整个文档)。您将只处理将div附加到x-foo的事件。
当你将很多不同的东西附加到父母身上时,这种技术真的很棒......例如,它非常适合听取添加某个类的div。
1)添加CSS
为要侦听其插入的元素添加非常短,不易察觉的动画。
注意:您必须在css前加上
<style>
x-foo > div {
animation-duration: 0.001s;
animation-name: nodeInserted;
}
@keyframes nodeInserted {
from { opacity: 0.99; }
to { opacity: 1; }
}
</style>
2)JS - 声明处理程序 - 回调
var nodeInsertedListener = function(event){
if (event.animationName == "nodeInserted") {
var node = event.target;
// call handler on new div
xfooHasNewDivHandler(node); // defined in next step
}
}
3)JS - 定义处理程序主体 - 在将div添加到x-foo时执行其代码的回调主体。 您也可以将此直接添加到处理程序
function xfooHasNewDivHandler(div) {
div.style.color = 'red';
//x-foo-has-new-div stuff...
}
4)注册事件监听器 - 告诉文档听取动画&#39;启动
['', 'MS', 'webkit'].forEach(function(prefix) {
var animEvtName = "AnimationStart";
prefix || (animEvtName = animEvtName.toLowerCase()),
(animEvtName = prefix+animEvtName);
document.addEventListener(prefix+animEvtName, nodeInsertedListener, false);
});
我认为这种方法很酷,希望它可以帮助任何人阅读。
答案 2 :(得分:0)
DOMNodeInserted is deprecated并从标准中移除,您应使用mutation observer,support is pretty good。
var parent = document.querySelector('x-foo');
var number_of_nodes = parent.childNodes.length;
var observer = new MutationObserver(function(mutations) {
if (parent.childNodes.length > number_of_nodes) {
number_of_nodes = parent.childNodes.length;
console.log('element added');
}
});
observer.observe(parent, {childList: true});
要停止收听,您需要致电observer.disconnect();