0

所以我使用了这个非常棒的工具,叫做 Visual Event,它显示了绑定到一个对象的所有事件处理程序 - 我注意到每次我点击或玩弄我的对象并检查绑定到它的事件处理程序列表时,有和每次更多。我的问题是这个:console.trace 或堆栈跟踪来确定 javascript 中错误的来源?在使用 Visual Event 和其他人的建议之后,我想我的问题是我可能一遍又一遍地将相同的处理程序绑定到相同的事件。有没有办法定期解除绑定?

我的应用程序有一堆插件连接到动态创建div的 s。这些divs可以调整大小并在该地方移动。该应用程序是一种编辑器,因此用户可以在他们喜欢的任何设计中排列这些 div(包含图像或文本)。如果用户单击一个 div,它就会“激活”,而页面上的所有其他 div 都会“停用”。我有一堆相关的插件,比如activateTextBox, initTextBox, deactivateTextBox,readyTextBox等等。每当第一次创建 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 或“文本框”包含在一个名为 的更大 divcontent中,这是我在其中的点击代码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光标需要很长时间才能恢复默认值。我停止拖动,但在准备好接受更多用户点击之前,一切都卡住了一段时间,等等。所以我猜问题必须是我将太多东西绑定到相同的事件需要在某些时候解除绑定观点?它变得如此糟糕,以至于 draggable 最终会在某个时候停止工作。文本框只是卡住了 - 它们仍然可以调整大小,但拖动停止工作。

4

1 回答 1

1

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

是的。看看你的代码:

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

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

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

  • 仅绑定一次事件处理程序,并使用布尔变量等跟踪当前状态。
  • 在绑定之前,删除所有其他已经绑定的事件处理程序。jQuery 的事件命名空间可以帮助您仅删除您自己的插件添加的那些。
  • 使用触发后自动取消绑定侦听器的one()方法。
于 2013-02-19T13:26:17.053 回答