事件监听器DOMNodeInserted被多次运行,为什么?

时间:2014-03-05 14:53:39

标签: javascript jquery javascript-events

我正在尝试侦听某个节点,该节点会动态地将某个类添加到DOM中。添加此节点后,我想向此节点添加插件的实例。我遇到的问题是DOMNodeInserted多次运行,然后在这个节点上运行我的插件多次导致问题。

页面上只出现过一次此类。

为什么会这样,我怎么能阻止这种情况发生呢?

    $(document).ready(function(){

    $('#editArea').live('DOMNodeInserted', '.class', function(e){

        $('.class').plugin({
            source: 'libs/ajax/somescript.php',
        });

    })

});

2 个答案:

答案 0 :(得分:6)

我在一段时间后遇到了同样的问题。你需要做的是去抖动函数,以便在最后一次DOMNodeInserted调用之后触发它。

试试这个(改编自John Hann的smartresize - 留下评论/链接):

(function ($, sr) {
        // debouncing function from John Hann
        // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
        var debounce = function (func, threshold, execAsap) {
            var timeout;
            return function debounced() {
                var obj = this, args = arguments;
                function delayed() {
                    if (!execAsap)
                        func.apply(obj, args);
                    timeout = null;
                };
                if (timeout) {clearTimeout(timeout);
                } else if (execAsap) {func.apply(obj, args);}
                timeout = setTimeout(delayed, threshold || 100);
            };
        }
        jQuery.fn[sr] = function (fn) { return fn ? this.on('DOMNodeInserted', debounce(fn)) : this.trigger(sr); };
    })(jQuery, 'debouncedDNI');

    $(document).ready(function () {
        $('#editArea').debouncedDNI(function () {
            $('.class').plugin({
                source: 'libs/ajax/somescript.php',
            });
        });
    });

答案 1 :(得分:4)

可能是因为在您的DOM中,您正在观看的任何元素都包含子元素。对匹配元素(.class)触发一次事件,对每个后代触发一次。

如果您需要观看的元素类似于select,其下面有一堆option元素,那么快速而肮脏的解决方案可能就是关注另一个"伙伴&#34 ;你可以在DOM中放置它的元素。例如:

$(document).ready(function(){
    $('#editArea').on('DOMNodeInserted', '#classbuddy', function(e){
        $('.class').plugin({
            source: 'libs/ajax/somescript.php',
        });
    })
});

然后在你的标记中你只需要添加一个像id="classbuddy"这样的空span元素。由于该范围不具有子元素,因此您的代码只会触发一次,因此.plugin()仅应用一次。