Javascript 将窗口调整大小事件静默绑定到jQuery插件而不保留对目标元素的引用的最佳方法

Javascript 将窗口调整大小事件静默绑定到jQuery插件而不保留对目标元素的引用的最佳方法,javascript,jquery,jquery-plugins,Javascript,Jquery,Jquery Plugins,我正在寻找最佳实践建议 我正在编写一个小jQuery插件来管理元素的水平滚动 // 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 = $.clea

我正在寻找最佳实践建议

我正在编写一个小jQuery插件来管理元素的水平滚动

// 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 );
    };
}
我需要该插件针对的所有dom元素在调整窗口大小时更新

事实上,我的网站是一个完整的ajax“应用程序”,所以当我删除DOM元素时,我需要它们消失,这样内存就不会泄漏

但是,如果不保留对DOM节点的引用,我无法找到绑定resize事件的方法

编辑:


实际上,我需要调整大小处理程序在“调用”时获取插件目标元素,因为我不想在内存中保留对这些元素的任何引用,因为我可能会在它们的父元素上调用.html(“”)

我没有粘贴所有的代码,只是一个空壳。我已经有了一个解除绑定处理程序的销毁方法。但是我正在动态地生成、删除和附加html节点,并将插件所针对的元素以静默方式删除

Kevin B说我可以重写jQuery
。remove
方法来处理处理程序,但必须加载jQuery UI才能工作。我也不想那样

以下是我尝试过的(尝试评论):


提前谢谢大家

您可以使用类名并转发调整大小事件:

$.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
$.fn.hScroll=函数(方法){
这
.addClass('hScroll')
.data('方法',参数)
};
var方法['alert_text']=函数(配置){
警报(配置+“”+$(this.text());
}
$(window.bind('resize.hScroll',function(){
$(“.hScroll”)。每个(函数(){
var method_config=$(this.data('method');
var method=method_config.shift();
//转发带有所有调整大小事件参数的调整大小事件:
方法[method].apply(此方法为配置方法);
})
})
//为所有a.test元素注册调整大小事件:
$(“a.test”).hScroll('alert_text','hey');
//每次都会提醒你“你好”

更新

如果更改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
var元素=[];
$.fn.hScroll=函数(方法){
push({'selector':this.selector,'arguments':arguments});
};
var方法['alert_text']=函数(配置){
警报(配置+“”+$(this.text());
}
$(window.bind('resize.hScroll',function(){
$。每个(元素,函数(i,元素){
$(element.selector).each(function(){
var method_config=element.arguments;
var method=method_config.shift();
//转发带有所有调整大小事件参数的调整大小事件:
方法[method].apply(此方法为配置方法);
})
})
})
//为所有a.test元素注册调整大小事件:
$(“a.test”).hScroll('alert_text','hey');
$(document.body).html(“您”);
//每次调整窗口大小时都会提醒“你好”

您应该在扩展中绑定滚动事件。此外,您还需要向扩展添加一个“destroy”方法。在从DOM中删除元素之前,需要调用此方法。在detroy方法中,您将希望解除调整大小事件的绑定


实现这一点的一个重要方面是,对绑定到resize事件的每个处理程序方法都有一个引用。或者,您可以在删除某个元素时解除所有调整大小事件的绑定,然后将滚动事件重新绑定到需要它的其余元素。

jQuery在执行删除或替换元素的操作时调用
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)

如果您使用的是jQueryUI小部件系统,您可以使用destroy方法,但是如果不是这样,您可以扩展
.remove
方法,让它也清理插件的功能。然后,您需要确保删除或替换元素的其他jQuery html方法在删除元素之前也使用
.remove
。我不会删除特定元素,而是删除包含这些元素的整个页面,因此我不会对元素调用.remove方法。您不会,但使用jQuery ui时,jQuery会这样做,这是当jQuery UI插件或其父插件被删除时自动清理它们的一部分。即使我在父插件上调用.html(“”)?是的,iirc。唯一的缺点(这是一个相当大的缺点)是必须包含jQueryUI核心和小部件工厂。您还必须在某种程度上使用widget工厂。Thx,我想定制类是一个解决方案。不过,我宁愿检查插件实现是否存在。还有,为什么不直接调用该方法而不是转发事件呢?因为所有元素可能都有不同的方法或不同的方法配置。我有一个destroy方法,可以解除处理程序的绑定,但为了清晰起见,没有粘贴它。我不想调用方法来解除事件绑定。这就是问题所在。然后只需解除影响已删除元素的单个事件的绑定。要做到这一点,您需要跟踪绑定到resize event的每个元素的每个事件处理程序。实际上,我需要resize处理程序在“调用”时获取插件目标元素,因为我不想在内存中保留对这些元素的任何引用,因为我可能会在它们的父元素上调用.html(“”),这很酷。我不确定我是否会使用它(一个特殊的类可能会更轻),但这就是我想要的答案。非常感谢!没问题,很抱歉,我很难准确地解释我的初衷。