#javascript #jquery #performance #jquery-events
#javascript #jquery #Производительность #jquery-события
Вопрос:
Влияет ли производительность, когда я перебираю элементы списка и добавляю обработчик кликов ко всем отдельным элементам?
Причина, по которой я это делаю, заключается в том, что я хотел бы сделать элемент списка интерактивным, только если он содержит гиперссылку.
Код, который я сейчас использую, это:
$('ul.paginator li').each(function() {
if ($('a', this).length > 0) {
$(this).css('cursor', 'pointer');
$(this).click(function() {
location.href = $('a', this).attr('href');
});
}
});
Ответ №1:
Я не уверен, насколько это может повлиять на производительность, но рассматривали ли вы возможность использования несколько упрощенного селектора jQuery:
$('ul.paginator li:has(a)').each(
function(){
$(this).css('cursor','pointer').click(
function(){
location.href = $(this).find('a').attr('href');
});
});
Кстати, производительность будет зависеть от количества элементов, которые вы просматриваете, больше, чем от чего-либо еще. Всего несколько, и это, вероятно, будет незаметно, несколько тысяч, и это (вероятно) будет заметно.
Отредактировано для снижения затрат на has()
:
$('ul.paginator li a').each(
function(){
var address = this.href;
$(this).closest('li').css('cursor','pointer').click(
function(){
location.href = address;
});
});
Это должно быть дешевле, так как оно будет выбирать только те a
элементы внутри li
, а затем перемещаться вверх, чтобы повлиять на этот li
элемент.
Комментарии:
1.
:has(a)
является дорогостоящим с точки зрения вычислений2. @David Thomas: отлично! не думал об
has()
этом! Именно то, что я искал. Я даже больше не используюeach()
. Теперь я могу просто сделать:$('ul.paginator li:has(a)').click(function() {}).css();
3. @Raynos: owh: ( Насколько это плохо?
4. @Raynos, это так; но больше, чем выполнение
if
инструкции для каждого элемента, возвращаемого селектором?5. @DavidThomas да, это так. лучше сделать это вручную, чем в селекторе, если только это не правильный селектор, а не поддельный jquery
Ответ №2:
зависит от того, сколько строк есть. Если их тысячи, то да. Если их небольшое количество, то этого недостаточно, чтобы быть заметным.
Альтернативным подходом было бы поместить обработчик щелчка в элемент, содержащий элементы, а затем, когда приходит событие щелчка, использовать данные в событии, переданном обработчику, чтобы определить, что делать. Один обработчик.
Ответ №3:
Да, лучше использовать delegate
с правильным селектором, который выбирает только нужные вам элементы.
Будет создан и подключен только один обработчик.
Если вы не хотите использовать has()
, этого будет достаточно (нет необходимости в нескольких обработчиках):
$('ul.paginator').delegate('click', 'li', function() {
var link = $('a', this);
if (link.length > 0) {
location.href = link.attr('href');
}
});
Комментарии:
1. Но дело в том, что для этого нет подходящего селектора. Поправьте меня, если я ошибаюсь.
2. Обновлен ответ, если вы не хотите использовать
has
3. Я бы добавил класс css (т. Е. ‘интерактивно’) для каждого
li
из них поa
мере их рендеринга (это решило бы многие проблемы). При текущем подходе я бы сделал$('ul.paginator').find('a').closest('li').css('cursor', 'pointer')