2011-01-11 3 views
3

У меня есть элемент, содержащийся в родительском элементе с классом active, например, так:Почему мой селектор jQuery не замечает, когда я удаляю класс?

<div class="active"> 
    <div class="button"></div> 
</div> 

У меня есть JQuery настроить для обработки нажмите на моем button DIV, но только при условии, что DIV содержится с помощью active родитель, например, так:

$('.active .button').click(function(){ 
    alert('Button clicked!'); 
}); 

Я использую JQuery, чтобы удалить active класс от родителей, и даже после удаления класса, предупреждение по-прежнему всплывает при нажатии на кнопку. Это кажется очень необычным, так как кнопка больше не соответствует критериям выбора. Это происходит в Chrome, Firefox и IE, поэтому, похоже, это намеренное поведение. Я что-то упускаю? или есть, по крайней мере, простой способ обход этого?

Вот простой пример JSFiddle для тестирования: http://jsfiddle.net/KjuDy/. Нажмите на поле в верхней строке. Это вызывает предупреждение и удаляет класс active, как и ожидалось. Проблема возникает, когда вы нажимаете кнопку в верхней строке, даже после того, как класс active исчез. Я бы ожидал, что предупреждение не появится, но оно все равно.

ответ

6

Обработчики назначаются один раз на основании результатов, найденных в селекторе при его запуске (я предполагаю, что DOM готов).

Изменение класса этих элементов после этого не влияет на обработчики, которые были связаны.

Если вы хотите, чтобы он был более динамичным, место a .delegate() обработчика вместо этого на предок элементов,

$('#someContainer').delegate('.active .button','click',function(){ 
    alert('Button clicked!'); 
}); 

Если единственный контейнер, который включает в себя все элементы, является <body>, а затем использовать это:

$('body').delegate('.active .button','click',function(){ 
    alert('Button clicked!'); 
}); 

Ваш пример, обновление:http://jsfiddle.net/KjuDy/1/

+0

Спасибо! Это отлично работало не только в упрощенном примере jsfiddle, но и в моем реальном проекте. У меня есть небольшое чтение, чтобы сделать это, я действительно понимаю, что здесь происходит, но по крайней мере мой проект работает на данный момент. –

+0

@ mlms13: Чтобы дать краткий обзор, функция '.delegate()' использует «делегирование событий». Многие типы на странице «пузырь». Другими словами, если вы нажмете на странице, то, начиная с самого глубокого вложенного элемента, который был нажат, он проверит, есть ли обработчик «щелчка», назначенный этому элементу. Если это так, он вызывает его. Затем он переходит к родительскому элементу этого элемента и делает то же самое и так далее, пока не достигнет корня документа. При «делегировании событий» вы размещаете обработчик событий в каком-либо родительском контейнере. Затем событие click, которое происходит внутри контейнера, будет пузыриться до него ... – user113716

+0

... и запустить его обработчик. Таким образом, метод jQuery '.delegate()' работает специально, состоит в том, что первый передаваемый вами аргумент - это * селектор *, который будет использоваться для проверки элемента * внутри *, который был нажат на контейнер. В вашем случае вы передаете '.active .button'. Таким образом, любой элемент внутри контейнера, который при нажатии будет соответствовать этому селектору, jQuery запустит обработчик. Вот почему нажимаем кнопку .button, которая происходит от '.active' вызывается обработчиком, но когда вы удаляете класс 'active', эта же кнопка больше не будет делать этого, потому что она больше не соответствует селектору. Надеюсь это поможет. – user113716

1

jQuery привязывается к элементам DOM, которые совпадают, когда вы впервые привязываете событие click.

Посмотрите на jQuery live.