我在这个jQuery代码中一遍又一遍地绑定事件吗?

时间:2013-02-19 13:18:13

标签: javascript jquery jquery-ui binding event-handling

所以我使用了这个totally awesome tool called Visual Event,它显示了绑定到一个对象的所有事件处理程序 - 我注意到每次我点击或玩弄我的对象并检查绑定到它的事件处理程序列表时,每次都是如此。我的问题是这个问题:console.trace or stack trace to pinpiont the source of a bug in javascript?在使用Visual Event和其他人的建议后,我认为我的问题是我可能会一遍又一遍地对相同的事件绑定相同的处理程序。有没有办法经常解开东西?

我的应用程序有一堆插件连接到动态创建的div。这些divs可以调整大小并在该地方移动。应用程序是一种编辑器,因此用户可以在任何他们喜欢的设计中安排这些div(包含图像或文本)。如果用户点击div,它将变为“激活”,而页面上的所有其他div将被“停用”。我有一堆相关的插件,例如activateTextBoxinitTextBoxdeactivateTextBoxreadyTextBox等等。每当首次创建div时,init插件只会在创建后第一次调用,如下所示:

$(mydiv).initTextBox();

readyTextBoxactivateTextBox以及deactivateTextBox经常被调用,具体取决于其他用户事件。

init中,我首先使用resizable()draggable()等绑定内容,然后将“准备好”框用于

    $.fn.extend({
        initTextBox: function(){
        return this.each(function() {
               // lots of code that's irrelevant to this question
               $this.mouseenter(function(){ 
        if(!$this.hasClass('activated'))
            $this.readyTextBox();
         }
         $this.mouseleave(function(){ 
        if($this.hasClass('ready')){
            $this.deactivateTextBox(); 
                    $this.click(function(e){
                 e.preventDefault();
                 });
                }
             });
     }); 
  });

以下是readyTextBox插件的简化摘要版本:

(function($){
    $.fn.extend({
        readyTextBox: function(){
        return this.each(function() {
               // lots of code that's irrelevant to this question
               $this.resizable({ handles: 'all', alsoResize: img_id});
               $this.draggable('enable');
               $this.on( "dragstop", function( event, ui )
               {/* some function */ });
               $this.on("resizestop", function( event, ui ){ /* another function */ });
               // and so on
});

然后是activateTextBox()

    $.fn.extend({
        activateTextBox: function(){
        return this.each(function() {
               // lots of code that's irrelevant to this question
               $this.resizable('option','disabled',true); //switch of resize & drag
               $this.draggable('option', 'disabled', true);
});

然后deactivate,我使用代码打开可拖动和可重新调整大小:

$this.draggable('enable'); $this.resizable('option','disabled',false);

这些div或“文本框”包含在名为content的较大div中,这是我在content中的点击代码:

$content.click(function(e){
    //some irrelevant code
     if( /* condition to decide if a textbox is clicked */) 
     {  $(".textbox").each(function(){ //deactivate all except this
        if($(this).attr('id') != $eparent.attr('id')) 
            $(this).deactivateTextBox();
        });
        // now activate this particular textbox
        $eparent.activateTextBox();
             }
          });

这几乎是与文本框相关的相关代码。为什么每当我拖动某些东西然后检查视觉事件时,有更多的点击次数和拖尾和鼠标移动比以前?此外,用户与页面交互的次数越多,事件完成所需的时间就越长。例如,我从div鼠标输出,但move光标需要 loooong 时间才能返回默认值。我放弃了拖动,但是在准备好接受更多用户点击之前,所有东西都会卡住一段时间等等。所以我猜测问题必须是我绑定了太多东西,同样的事件需要在一些事情上解除绑定点?它变得非常糟糕,拖车最终会在某个时刻停止工作。文本框刚刚被卡住 - 它们仍然可以调整大小,但拖动仍然无法正常工作。

1 个答案:

答案 0 :(得分:1)

  

我是否一遍又一遍地绑定事件

是。看看你的代码:

$this.mouseenter(function(){ 
    …
    $this.mouseleave(function(){ 
        …
        $this.click(function(e){
            …
        });
    });
});

这意味着每次鼠标悬停元素时,都会添加另一个离开处理程序。当你离开元素时,每个处理程序都会添加另一个点击事件。

我不确定你想做什么,但有几种选择:

  • 仅绑定事件处理程序一次,并使用布尔变量等跟踪当前状态。
  • 绑定之前,删除已绑定的所有其他事件处理程序。 jQuery的event namespacing可以帮助您只删除自己添加的插件。
  • 使用one() method在触发后自动取消绑定侦听器。