2013-02-19 2 views
0

Итак, я использовал это totally awesome tool called Visual Event, в котором показаны все обработчики событий, привязанные к объекту, - и я заметил, что каждый раз, когда я нажимал или играл с моим объектом и проверял список связанных с ним обработчиков событий, , Моя проблема заключается в следующем: console.trace or stack trace to pinpiont the source of a bug in javascript? После использования Visual Event и чье-то предложение я думаю, что моя проблема в том, что я, вероятно, привязываю одни и те же обработчики к тем же событиям снова и снова. Есть ли способ регулярно развязывать вещи?Я связываю события снова и снова в этом коде jQuery?

Мое приложение имеет кучу плагинов, подключаемых к динамически созданным div. Эти divs могут быть изменены и перемещены вокруг места. Приложение является своего рода редактором, поэтому пользователи упорядочивают эти div (которые содержат изображения или текст) в любом дизайне, который им нравится. Если пользователь нажимает на div, он становится «активированным», а все остальные div на странице «деактивируются». У меня есть куча связанных плагинов, таких как activateTextBox, initTextBox, deactivateTextBox, readyTextBox и так далее. Всякий раз, когда ДИВ сначала создается, init плагин вызывается один раз, только в первый раз после создания, например, так:

$(mydiv).initTextBox(); 

Но readyTextBox и activateTextBox и 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);

Эти дивы, или «Textboxes» содержатся в большом DIV называется content, и это код нажмите I есть в 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(); 
      } 
      }); 

Это в значительной степени соответствующий код, связанный с текстовыми полями. Почему каждый раз, когда я перетаскиваю что-то вокруг, а затем проверяю Visual Event, есть больше кликов и перетаскиваний и мышь, чем раньше? Кроме того, чем больше пользователь взаимодействует со страницей, тем больше времени происходит для завершения событий. Например, я выворачиваю из div, но курсор move принимает loooong время, чтобы вернуться к умолчанию. Я перестаю перетаскивать, но все время задерживается, прежде чем готовиться к большему количеству кликов пользователей и т. Д. Поэтому я предполагаю, что проблема заключается в том, что я связываю слишком много вещей с тем же самым событием, которое нужно отменить на некоторых указать? Это становится настолько плохо, что перетаскиваемый в конечном итоге перестает работать в какой-то момент. Текстовые поля просто застревают - они все еще могут быть изменены, но перетаскивание перестает работать.

ответ

1

Am I связывании события снова и снова

Да.Посмотрите на код:

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

Это означает, что каждый раз, когда вы наводите указатель на элемент, вы добавляете еще один обработчик. И когда вы покидаете элемент, каждый из этих обработчиков добавляет еще одно событие click.

Я не уверен, что вы хотите сделать, но есть несколько вариантов:

  • связывают обработчики событий только один раз, и следить за текущим состоянием с булевыми переменными и т.д.
  • перед тем bind, удалить все остальные обработчики событий, которые уже связаны. jQuery's event namespacing может помочь вам удалить только те, которые добавили ваш собственный плагин.
  • использует one() method, который автоматически отсоединяет слушателя после его запуска.
+0

Но 'initTextBox()' вызывается только один раз, в первый раз. Итак, как мне написать первые привязки? Или лучше сделать что-то вроде 'if (! Bound (this.mouseleave)) {// только тогда сделать привязку //}' (псевдокод) – user961627

Смежные вопросы