检测何时将元素添加到自定义元素

时间:2013-12-27 20:54:34

标签: javascript html5 events

我想检测是否从自定义元素添加(或删除)元素。例如,请考虑以下自定义元素

<x-foo>
    <div></div>
    <div></div>
    <div></div>
</x-foo>

现在我可以简单地添加一个元素

document.querySelector('x-foo').appendChild(document.createElement('div'));

有没有例如生命周期回调方法(就像属性更改一样)来检测这个?

3 个答案:

答案 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 observersupport 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();