Один обработчик кликов для нескольких элементов?
Я хочу добавить обработчик кликов в div. Но есть ли способ использовать одну функцию обработчика кликов и делиться ею между несколькими div? Поскольку у меня может быть 100 div, я не хочу создавать обработчик кликов для каждого (все они будут практически делать то же самое). Пример jquery показывает:
$("p").click(function () {
$(this).foo();
});
можем ли мы сделать что-то вроде:
$("p").click(myClickHandler);
function myClickHandler(source) {
source.foo();
}
?
Ответы
Ответ 1
jQuery .delegate()
метод - отличный способ, если вы не хотите накладных расходов сотен событий щелчка.
Он назначает одно событие контейнеру, который запускается, когда указанные потомки контейнера получают событие.
Протестируйте пример: https://jsfiddle.net/jYKgm/210/
HTML
<div id="container"> // #container has the event handler assigned
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
</div>
JQuery
// The click event handler will fire when <div> elements
// that descend from #container get clicked.
$('#container').delegate('div', 'click', function() {
alert('index ' + $(this).index() + ' was clicked');
});
Это назначит один обработчик элементу #container
и сделает его таким, чтобы любые элементы-потомки div
запускали обработчик.
Итак, если есть 500 потомков div
, все они будут совместно использовать один обработчик событий.
- .delegate()
- http://api.jquery.com/delegate
Ответ 2
Если все они принадлежат одному и тому же элементу:
<div id="lol">
<p>blah</p>
<p>slfk</p>
</div>
Вы можете сделать
$('#lol').click(function(e){
alert( $(e.target).text() );
});
Вы также можете применить его к документу. Таким образом вы устанавливаете элемент click
на 1 и захватываете target
. Вы можете добавить логику, чтобы убедиться, что ее абзац и еще что-то еще.
Это будет использовать только литерал одной функции и другие функции. Меньше накладных расходов, чем .delegate
, потому что он делает это на месте вместо внутреннего.
Ответ 3
Для пользователей, работающих с новыми версиями jQuery (1.7 или новее), вы можете попробовать . on().
Повторное использование сценария примера HTML в другом ответе:
<div id="container"> // #container has the event handler assigned
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
</div>
jQuery будет просто:
$('div#container').on('click', 'div', function() { alert('Hi Mom!'); });
Код выглядит очень похоже на тот, который используется для примера .delegate()
.
Я столкнулся с ситуацией, когда мы искали теги <a>
и применяли специальные события click. Для страниц с сотнями тегов <a>
для запуска jQuery потребовалось несколько секунд. Переключение на функцию .on()
, примененную к телу тела, сменило время до почти ничего.
Ответ 4
Да.
Нет необходимости (или способности) передавать отдельный параметр source
. Объект this
был доступен в вашей анонимной функции, и он также будет доступен в вашей именованной функции. Он будет, как всегда, быть объектом, который был нажат.
function myClickHandler() {
$(this).foo();
}
Ответ 5
Да, вы можете использовать один и тот же обработчик для нескольких div. Как показано, это будет установлено на элемент, который был нажат, и вы можете использовать его, как хотите. Он не будет передан в качестве аргумента, поэтому ваш второй пример не работает.
$("div.someclass").click(myClickHandler);
function myClickHandler() {
$(this).foo();
}
Ответ 6
Рассмотрим этот код:
$('div').bind('click', eventHandler);
eventHandler = function () { ... }