почему программисты говорят, что "живой" неэффективно?
Я полагаю, что это неэффективно, поскольку обработчик размещается в корневом узле и полагается на пузырение, чтобы поймать событие и запустить нужный обработчик.
Одной из альтернатив может быть просто привязка
обработчика к динамически создаваемым элементам, когда они создаются и добавляются в DOM.
Другая альтернатива - привязать один обработчик к контейнеру, и пусть ваши события проникают в него. Это может быть удобно, если в контейнер добавлено много одинаковых элементов.
<div id="myContainer">
<div class="myElement>element</div>
<div class="myElement>element</div>
<div class="myElement>element</div>
<div class="myElement>element</div>
</div>
Привяжите обработчик нажатия к #myContainer
вместо каждого .myElement
.
$('#myContainer').click(function(e) {
$target = $(e.target);
if($target.closest('.myElement').length) {
// Run my code for the click
}
});
Я думаю, что это может страдать от тех же неэффективностей, что и .live()
, но должно быть лучше, поскольку это более локализовано. Добавлены новые элементы .myElement
, работающие автоматически.
EDIT:
Согласно документации: Начиная с jQuery 1.4, всплеск событий может опционально останавливаться на "контексте" элемента DOM.
Похоже, это создаст эффект, схожий с последним методом, который я упомянул.
EDIT:
Как предложил Ник Крейвер, метод jQuery .delegate()
может создать подобный эффект более чисто.
Пример, любезно предоставленный Ником:
$('#myContainer').delegate('.myElement', 'click' function() { alert($(this).text()); });
live ()
может считаться неэффективным, только если:
Если ваш вариант использования соответствует вышеуказанным критериям (особенно №2), вам следует придерживаться прямой привязки к элементам и избегать live ()
.
Пример тестирования производительности live ()
, который вы можете попробовать, - это профилирование фрагмента кода, который использует live ()
для привязки щелчка
обработчик элемента, а также профилирует другой фрагмент кода, который использует click ()
для привязки к тому же элементу.
Я не совсем уверен, какой у вас будет конечный результат, но уверен, что это будет интересно.
Как @patrick предполагает, что это может быть неэффективным, поскольку требует обработки всех событий в документе, независимо от того, достигает ли пузырь вашего элемента или нет.
Именно здесь delegate может помочь, поскольку он работает так же, как и в реальном времени, но позволяет ему влиять только на меньшую часть документа, ограничивая его общим родителем
(используя его пример)
$('#myContainer').delegate('div.myElement', 'click', function(){});