Я пытаюсь понять лучшие практики для ненавязчивого Javascript. Каков рекомендуемый и эффективный способ использования наблюдателей? - PullRequest
2 голосов
/ 20 февраля 2011

Я пытаюсь понять лучшие практики для ненавязчивого Javascript. Среди идей ненавязчивого Javascript заключается в том, что Javascript не должен быть непосредственно включен в HTML-код страницы, например onchange=runScript(). Вместо этого должен быть создан наблюдатель для выполнения кода при каждом изменении рассматриваемого элемента.

Мои вопросы - это лучшие практики, которые окружают наблюдателей. Сколько накладных расходов у наблюдателя событий в Javascript?

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

document.body.observe('click', function(event) {
  if (event.element().match('some_id')) {
    //do something
    event.stop()
  }
}

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

$('some_id').observe('click', function(event) {
  //do something
  event.stop()
}

Или это наблюдатели с такими низкими издержками, что вообще нет причин беспокоиться об этом, и я должен просто сделать то, что удобнее кодировать?

Ответы [ 2 ]

2 голосов
/ 21 февраля 2011

Хотя вы написали JavaScript в заголовке, я вижу, вы использовали jQuery в своем вопросе.Итак, надеюсь, что jQuery-ориентированный ответ в порядке.

jQuery включает в себя два способа сделать это: $.live() и $.delegate().Это определенно хорошая идея использовать делегирование событий при обработке событий из большого количества связанных элементов (например, каждой отдельной строки большой таблицы).Присоединение отдельного обработчика к таблице и отслеживание событий по мере их всплытия более эффективно, чем присоединение события к каждой отдельной строке.

Для отдельных элементов (как, например, ваш пример идентификатора) делегирование событий не требуется.Простое $('#some_id').click(fn) отлично.

1 голос
/ 21 февраля 2011

Безусловный, «эффективный» слишком широк, чтобы говорить, что один метод является наиболее эффективным. Например, есть эффективность времени и пространства, и часто между ними есть компромисс. Кроме того, различные браузеры могут свободно реализовывать события, как они считают нужным, при условии, что они ведут себя так, как диктует стандарт W3C , ограничивающий выводы о стоимости времени и пространства.

Мы можем проанализировать затраты и эффективность в отношении потока событий . В каждом совместимом браузере событие сначала запускается в корневом элементе, затем в каждом промежуточном дочернем элементе, пока не достигнет цели, затем событие возвращается обратно к корню, снова вызывая промежуточные элементы. При выполнении каждого шага вниз и вверх по структуре документа во время потока событий будет затрачиваться время (выяснение, какой элемент активировать, поиск слушателей и т. Д.), Поэтому, если вы можете остановить событие как как можно раньше во время потока (как в вашем первом примере) есть потенциальная экономия времени. Конечно, специальная обработка каждой цели может компенсировать любой выигрыш, и может быть некорректно останавливать событие раньше.

Создание отдельной, но равной функции слушателя для каждого из набора элементов может привести к ненужным затратам памяти. Обратите внимание, что это не то же самое, что подписать одну и ту же функцию на несколько объектов. Например:

for (var i=0; i < elements.length; ++i) {
    elements[i].observe('click', function (evt) {...});
}

может потребоваться больше памяти, чем:

elements.each('click', function (evt) {...});

Если JS engine interns функционирует, они будут использовать одинаковый объем памяти.

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

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

...