我正在寻找最佳实践建议。
我正在编写一个小的jQuery插件来管理元素的水平滚动。
我需要该插件所针对的所有dom元素来更新窗口大小。
事实是,我的网站是一个完整的ajax'app',所以当我删除DOM元素时,我需要它们,所以内存不会泄漏。
但是我找不到一种方法来绑定resize事件而不保留对DOM节点的引用。
编辑:
实际上我需要调整大小处理程序来在'调用'时获取插件目标元素,因为我不想在内存中保留对这些元素的任何引用,因为我可能会调用.html('' )他们的父母 ......
我没有粘贴所有代码,只是一个空shell。我已经有一个取消绑定处理程序的destroy方法。但是我正在动态地生成,删除和追加html节点,并且插件所针对的元素将以静默方式删除。
Kevin B表示我可以覆盖jQuery .remove
方法来处理处理程序,但是必须加载jQuery UI才能工作。我不想要那个..
这是我尝试过的(尝试评论过):
(function($) {
// SOLUTION 2 (see below too)
// Not good either coz elements are not removed until resize is triggered
/*
var hScrolls = $([]);
$(window).bind('resize.hScroll',function(){
if(!hScrolls.length) return;
hScrolls.each(function(){
if($(this).data('hScroll')) $(this).hScroll('updateDimensions');
else hScrolls = hScrolls.not($(this));
});
});
*/
// END SOLUTION 2
// SOLUTION 3 (not implemented but I think I'm on the right path)
$(window).bind('resize.hScroll',function(){
// need to get hScroll'ed elements via selector...
$('[data-hScroll]').hScroll('updateDimensions');
// I don't know how....
});
// END SOLUTION 3
var methods = {
init : function(options) {
var settings = $.extend( {
defaults: true
}, options);
return this.each(function() {
var $this = $(this),
data = $this.data('hScroll');
if (!data) {
$this.data('hScroll', {
target: $this
});
// SOLUTION 1
// This is not good: it keeps a reference to $this when I remove it...
/*
$(window).bind('resize.hScroll', function(){
$this.hScroll('updateDimensions');
});
*/
// END SOLUTION 1
$this.hScroll('updateDimensions');
// SOLUTION 2 (see above too)
hScrolls = hScrolls.add(this);
}
});
},
updateDimensions: function(){
var hScroll = this.data('hScroll');
// do stuff with hScroll.target
}
}
$.fn.hScroll = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if ( typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.hScroll');
}
};
})(jQuery);
提前全部谢谢!
答案 0 :(得分:2)
cleanData
(是的,即使您使用parent.html("")
)。您可以通过扩展它并使其触发目标元素上的事件来利用它。
// This is taken from https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js 10/17/2012
if (!$.widget) { // prevent duplicating if jQuery ui widget is already included
var _cleanData = $.cleanData;
$.cleanData = function( elems ) {
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
try {
$( elem ).triggerHandler( "remove" );
// http://bugs.jquery.com/ticket/8235
} catch( e ) {}
}
_cleanData( elems );
};
}
现在,您可以在设置插件时绑定到remove事件并让它运行您的destroy方法。
$(elem).bind("remove",methods.destroy)
答案 1 :(得分:1)
您可以使用班级名称并转发调整大小事件:
$.fn.hScroll = function(method) {
this
.addClass('hScroll')
.data('method', arguments)
};
var methods['alert_text'] = function(config){
alert( config + " " + $(this).text() );
}
$(window).bind('resize.hScroll',function(){
$(".hScroll").each(function(){
var method_config = $(this).data('method');
var method = method_config.shift();
// Forward the resize event with all resize event arguments:
methods[method].apply(this, method_config);
})
})
// Register a resize event for all a.test elements:
$("a.test").hScroll('alert_text', "hey");
// Would alert "hey you" for <a class="test">you</a> on every resize
更新
如果您更改dom并想要保留选择器,您可以试试这个:
var elements = [];
$.fn.hScroll = function(method) {
elements.push({'selector' : this.selector, 'arguments' : arguments });
};
var methods['alert_text'] = function(config){
alert( config + " " + $(this).text() );
}
$(window).bind('resize.hScroll',function(){
$.each(elements,function(i, element){
$(element.selector).each(function(){
var method_config = element.arguments;
var method = method_config.shift();
// Forward the resize event with all resize event arguments:
methods[method].apply(this, method_config);
})
})
})
// Register a resize event for all a.test elements:
$("a.test").hScroll('alert_text', "hey");
$(document.body).html("<a class='test'>you</a>");
// Would alert "hey you" for every window resize
答案 2 :(得分:0)
您应该在扩展程序中绑定滚动事件。此外,您还需要在扩展中添加“destroy”方法。在从DOM中删除元素之前,您需要调用此方法。在detroy方法中,您将要取消绑定resize事件。
使这项工作的一个重要事项是您可以引用绑定到resize事件的每个处理程序方法。或者,您可以在删除元素时取消绑定所有调整大小事件,然后将滚动事件重新绑定到需要它的其余元素。