我正在尝试侦听某个节点,该节点会动态地将某个类添加到DOM中。添加此节点后,我想向此节点添加插件的实例。我遇到的问题是DOMNodeInserted多次运行,然后在这个节点上运行我的插件多次导致问题。
页面上只出现过一次此类。
为什么会这样,我怎么能阻止这种情况发生呢?
$(document).ready(function(){
$('#editArea').live('DOMNodeInserted', '.class', function(e){
$('.class').plugin({
source: 'libs/ajax/somescript.php',
});
})
});
答案 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()
仅应用一次。