2014-09-29 3 views
0

На моей странице пользователь нажимает на элемент, чтобы его отредактировать. Чтобы облегчить это, я назначаю класс editable всем таким элементам.Рекомендации по размещению прослушивателей событий

Как прослушивать клики по всем этим элементам? В настоящее время я делаю это:

$lib.addEventListener(document.body, "click", function(event) { 
    if($lib.hasClass(event.target, "editable") { 
    // do stuff 
    } 
}); 

где $lib является немного библиотека JS я использую.

Альтернативой было бы установить слушателя на каждом элементе, как это:

var editables = document.getElementsByClassName("editable"); 
for(var i = 0; i < editables.length; i++) { 
    $lib.addEventListener(editables[i], "click", editElement); 
} 

Мне кажется, что первый способ должен быть лучше для работы, так как это только один элемент прислушиваются, но возможно ли ухудшить производительность, связав все такие события с элементом тела? Есть ли какие-либо другие соображения (например, реализация браузеров обработки событий), которые я пренебрегаю, что предложило бы сделать это вторым способом?

+1

Обратите внимание, что ваш первый фрагмент не нажимает на дочерние элементы ваших редактируемых материалов, в то время как второй фрагмент делает. – Bergi

ответ

1

Короткий ответ: определенно сделайте это в первую очередь. Делегирование событий является более эффективным, но требует дополнительных условий в коде, так что это в основном сложность и компромисс между производительностью.

Longer Answer: Для небольшого количества элементов добавление отдельных обработчиков событий отлично работает. Однако, когда вы добавляете все больше обработчиков событий, производительность браузера начинает ухудшаться. Причина в том, что прослушивание событий - интенсивное использование памяти.

Однако в DOM события «пузырятся» от самой конкретной цели до самого общего запуска любых обработчиков событий на этом пути. Вот пример:

<html> 
    <body> 
     <div> 
      <a> 
       <img> 
      </a> 
     </div> 
    </body> 
</html> 

Если вы нажали на <img> теге, что событие щелчка уволит обработчики событий в таком порядке:

  1. IMG
  2. ДИВ
  3. тела
  4. html
  5. document объект

делегация Событие является метод прослушивания родителей (скажем <div>) для связки обработчиков событий вместо конкретного элемента вы заботитесь о (скажем <img>). Объект события будет иметь целевое свойство, которое указывает на определенный элемент dom, из которого возникло событие (в данном случае <img>).

Ваш код для делегирования событий может выглядеть примерно так:

$(document).ready(function(){ 
    $('<div>').on('click', function(e) { 
     // check if e.target is an img tag 
     // do whatever in response to the image being clicked 
    }); 
}); 

Для или DuckDuckGo «делегирование событий» больше информации Checkout Дэйва Уолша blog post on Event Delegation.

ЗАПИСКА образец кода в OP: В первом примере, target.hasClass('editable') означает, что конкретная вещь щелкнул, должен иметь класс редактируемые для если блок для выполнения. Как заметил один из комментаторов, это, вероятно, не то, что вы хотите. Вы можете попробовать что-то вдоль этих линий вместо:

$(document).on('click', function(e) { 
    if ($(e.target).parents(".editable").length) { 
     // Do whatever 
    } 
}); 

Давайте разберем, что вниз немного:

  • $(e.target) - все, что на странице, которая была щелкнул преобразуется в JQuery
  • .parents(".editable") - найти все предки элемента щелкнули, а затем фильтруют только те, которые имеют класс «редактируемый»
  • .length - это должно быть целое число. Если 0, это означает, что нет родителей с «редактируемым» классом
+0

Благодарим вас за подробный ответ. –

Смежные вопросы