Почему при запуске $ .click () несколько раз, и если ссылка нажимается один раз, она захватывает ее более одного раза? - PullRequest
1 голос
/ 04 декабря 2011

У меня есть что-то вроде:

function init(){
  $('.btn').click(function(){
    //do something;
  }
}

И когда новый контент добавляется через ajax, я звоню init(), так что событие нажатия применяется к новым кнопкам.Но когда я нажимаю на него один раз, он захватывает несколько щелчков (столько раз, сколько я звонил init()).Это имеет смысл, но как этого избежать?

jsFiddle link: http://jsfiddle.net/s2ZAz/8/


Решения:
* Использование $ .delegate () -http://api.jquery.com/delegate/
* Используйте $ .live () - http://api.jquery.com/live/

Менее предпочтительные, но все же решения:
* Используйте $ .off () - http://api.jquery.com/off/ или $.unbind () - http://api.jquery.com/unbind/

Ответы [ 4 ]

2 голосов
/ 04 декабря 2011

click говорит: «для каждого объекта, соответствующего селектору, подключите этот приемник щелчков». Вы, вероятно, хотите что-то более похожее на delegate с надписью «для каждого объекта, который когда-либо будет соответствовать этому селектору, подключите этот слушатель».

$(document).delegate('button', 'click', function() {
});

Вы все равно получите двойной обратный вызов, если дважды позвоните init, но при этом не будет дважды для вызова init, потому что при добавлении новых объектов они будут уже назначены для прослушивания кликов.

Обратите внимание, что document выше следует заменить ближайшим постоянным предком, согласно комментарию Грега ниже.

Демо .

Начиная с jQuery 1.7, вы можете предпочтительно использовать функцию .on() для достижения того же эффекта.

Демо .

2 голосов
/ 04 декабря 2011

Вы можете использовать метод unbind для удаления обработчика событий (или метод off, если вы используете новый синтаксис jQuery 1.7 для присоединения обработчиков)

Еще лучше, вы можете использоватьlive метод, чтобы настроить обработчик событий для любых элементов, которые будут добавлены на страницу в будущем и соответствуют заданному селектору.Таким образом, вам нужно вызвать init только один раз.

1 голос
/ 04 декабря 2011
$("body").delegate("button", "click", function() {
    alert('I\'m annoying!');
});

$('div').append("<button>Click me, I will alert twice</button><br/>");

$('div').append("<button>Click me, I will alert once</button><br/>");

$('div').append("<button>Click me, I will not alert at all</button><br/>");

Попробуйте

0 голосов
/ 04 декабря 2011

Как упомянул Дэвид и в соответствии с примером делегата liho (мне понравилось, как скрипка каскадировалась, сколько раз всплыло предупреждение !!), проблема заключается в нескольких привязках, которые можно решить с помощью .live() (устарело)или .delegate() (исключается) или .on() (предпочтительный).Однако было бы ошибкой делегировать прослушивание документа или даже узла body с точки зрения производительности.

Лучший способ сделать это - определить предка кнопки, которая никогда не будет уничтожена.body - это простой выбор, но почти всегда мы создаем наши страницы с помощью элементов-обёрток, которые вложены на один или несколько уровней глубже, чем body, и поэтому позволяют устанавливать меньше слушателей.

HTML:

<div id="someWrapper">
  <div class="somethingThatGetsDestroyed">
    <button>Click Me</button>
  </div>
</div>

JS с использованием jQuery 1.7 +:

$('#someWrapper').on('click', 'button', function() {
  alert('Clickity-click!');
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...