jQuery: функция вызывается дважды. Распространение? Почему это происходит?

#jquery #stoppropagation

#jquery #остановка распространения

Вопрос:

Пожалуйста, взгляните на следующую скрипку: http://jsfiddle.net/K9NjY /

Я потратил 3-4 часа на этот код и сузил его до самой короткой версии, и теперь я застрял.

Проблема: 1. Нажмите «divOne» 2. Нажмите переключатель DivNames 3. Нажмите ‘divTwo’

* Почему divOne все еще получает предупреждение? Как мне это остановить? * Логика подсказывает мне, что при нажатии divTwo мы должны получить только одно предупреждение с надписью «divTwo»

Обратите внимание, что doSomething() внутри него есть функция, которая запускается a click . Это не может измениться, т.Е. $("." divName).click(function(){...}); должно оставаться внутри doSomething()

Что я могу с этим поделать?

Ответ №1:

События привязываются к элементам, а не к их именам классов, всякий раз, когда вызывается функция, вы прикрепляете обработчик щелчка к соответствующему элементу. Вот почему вы видите, что вызывается несколько обработчиков. Вы можете либо использовать делегирование событий с помощью переданного параметра, либо использовать off метод удаления обработчиков.

редактировать: обычно, когда вы присоединяете несколько обработчиков к элементу, вы делаете что-то не так. Присоединение обработчиков событий к другим обработчикам — это путь к боли. Вместо этого логика должна быть перемещена в тело обработчика.

Это то, что я, вероятно, сделал бы в этом случае:

 var $e = $(".action").on('click', function() {
     var action = $(this).data('action');
     // Do something based on the element's current `action` datum
     if (action === 'whatever') {
       // ...
     } else {
       // ...
     }
});

function doSomething(divName) {
    $e.html(divName).data('action', divName);
}
  

Здесь action данные могут использоваться в логике обработчика.

Комментарии:

1. Как бы я использовал off метод в этом сценарии, пожалуйста?

Ответ №2:

Удалите прослушиватели событий с помощью off и добавьте снова, переключение имен классов не приведет к отключению существующих прослушивателей событий —

 function doSomething(divName){

    $(".action").off().addClass(divName).html(divName).click(function(){
        alert(divName);
    });
}
  

СКРИПКА

Ответ №3:

Если вы используете Google Chrome, самый простой способ найти подобные вещи — использовать представление компонента. Вы можете видеть там, что перед щелчком по имени переключателя div первый div выглядит следующим образом:

 <div class="action divOne">divOne</div>
  

после нажатия на нее это выглядит так

 <div class="action divOne divTwo">divTwo</div>
  

это означает, что вы только что добавили divTwo, но никогда не удаляли divOne. Вы также вызываете функцию, которая, в свою очередь, вызывалась при запуске скрипта.

Где вы говорите:

 doSomething("divOne");//First call on Dom Ready
  

Он уже вызывает эту функцию. Вот почему вы получаете как divOne, так и divTwo в качестве ответа после переключения.

Этот обновленный будет функционировать так, как вы ожидаете. http://jsfiddle.net/K9NjY/2 /

Комментарии:

1. У @Johnbabu Koppolu есть лучшее решение, если вы хотите сохранить свой текущий макет.