Каков наилучший способ добавить событие в JavaScript?

Я вижу 2 основных способа установки событий в JavaScript:

  1. Добавьте событие прямо внутри тега следующим образом:

    <a href="" onclick="doFoo()">do foo</a>

  2. Установите их с помощью JavaScript следующим образом:

    <a id="bar" href="">do bar</a>

и добавить событие в <script> раздел внутри <head> раздел или во внешнем файле JavaScript, например, если вы используете prototypeJS:

Event.observe(window, 'load', function() {
    $('bar').observe('click', doBar);
}

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

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

Какой метод самый лучший?

Убийственный ответ будет полностью оценен!

6 ответов

Решение

По моему опыту, есть два основных момента к этому:

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

2) Второй вид, т.е. Event.observe() имеет преимущества, когда одно и то же или очень похожее действие выполняется для нескольких событий, потому что это становится очевидным, когда все эти вызовы находятся в одном и том же месте. Также, как указал Конрад, в некоторых случаях это может быть выполнено одним вызовом.

Я думаю, что первый метод легче читать и поддерживать

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

Объявление всех событий в одном центральном месте помогает организовать действия, происходящие на сайте. Если вам нужно что-то изменить, вам не нужно искать все места, вызывающие функцию, вы просто должны изменить это в одном месте. При добавлении большего количества элементов, которые должны иметь такую ​​же функциональность, вам не нужно забывать добавлять к ним обработчики; вместо этого часто достаточно позволить им объявить класс или даже вообще не изменять их, потому что они логически принадлежат элементу контейнера, все дочерние элементы которого связаны с действием. Из фактического кода:

$$('#itemlist table th > a').invoke('observe', 'click', performSort);

Это связывало обработчик событий со всеми заголовками столбцов в таблице, чтобы сделать таблицу сортируемой. Представьте себе, что все заголовки столбцов можно сортировать отдельно.

Я считаю, что второй метод, как правило, предпочтительнее, потому что он хранит информацию о действии (то есть JavaScript) отдельно от разметки так же, как CSS отделяет представление от разметки.

Я согласен, что из-за этого немного сложнее увидеть, что происходит на вашей странице, но хорошие инструменты, такие как firebug, помогут вам в этом. Вы также найдете гораздо лучшую доступную поддержку IDE, если сведете к минимуму смешивание HTML и Javascript.

Этот подход действительно вступает в свои права по мере роста вашего проекта, и вы обнаружите, что хотите присоединить одно и то же событие javascript к группе различных типов элементов на многих разных страницах. В этом случае становится намного проще иметь один темп, который присоединяет события, а не искать много разных файлов HTML, чтобы найти, где вызывается определенная функция.

Вы также можете использовать addEventListener (не в IE) / attachEvent (в IE).

Проверьте: http://www.quirksmode.org/js/events_advanced.html

Они позволяют вам присоединить функцию (или несколько функций) к событию в существующем объекте DOM. У них также есть преимущество, позволяющее позже отсоединять приложение.

В общем, если вы используете значительное количество javascript, может быть полезно сделать ваш javascript читабельным, в отличие от вашего html. Так что вы могли бы сказать, что onclick=X в html это очень ясно, но это и недостаток разделения кода - еще одна синтаксическая зависимость между частями - и случай, когда вам нужно прочитать html и javascript, чтобы понять динамическое поведение страницы,

Мое личное предпочтение - использовать jQuery во внешних js-файлах, чтобы js был полностью отделен от html. Javascript должен быть ненавязчивым, так что встроенный (т.е. первый пример), на мой взгляд, не самый лучший выбор. При просмотре html единственным признаком того, что вы используете js, должен быть сценарий, включенный в заголовок.

Примером прикрепления (и обработки) событий может быть что-то вроде этого

var myObject = {

    allLinkElements: null,  

    init: function()
    {
        // Set all the elements we need
        myObject.setElements();

        // Set event handlers for elements
        myObject.setEventHandlers();
    },

    clickedLink: function()
    {
        // Handle the click event
        alert('you clicked a link');
    },

    setElements: function()
    {
        // Find all <a> tags on the page
        myObject.allLinkElements = $('a');

        // Find other elements...
    },

    setEventHandlers: function()
    {
        // Loop through each link
        myObject.allLinkElements.each(function(id)
        {   
            // Assign the handler for the click event
            $(this).click(myObject.clickedLink);
        });

        // Assign handlers for other elements...
    }
}

// Wait for the DOM to be ready before initialising
$(document).ready(myObject.init);

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

Конечно, огромная выгода от того, что jQuery (или другая хорошо известная библиотека) выполняет тяжелую работу, заключается в том, что кросс-браузерная поддержка (в значительной степени) заботится о том, что делает жизнь намного проще

Библиотеки, такие как YUI и jQuery, предоставляют методы для добавления событий только после того, как DOM будет готов, что может быть до window.onload. Они также гарантируют, что вы можете добавить несколько обработчиков событий, чтобы вы могли использовать сценарии из разных источников, без того, чтобы разные обработчики событий перезаписывали друг друга.

Итак, ваш практический выбор;

Один. Если ваш скрипт простой и единственный, который когда-либо будет запускаться на странице, создайте функцию init следующим образом:

window.onload = function () {
    init();
}
function init() {
    // actual function calls go here
    doFoo();
}

Два. Если у вас много сценариев или вы планируете смешивать сценарии из разных источников, используйте библиотеку и ее onDOMReady способ безопасно добавить ваши обработчики событий

Другие вопросы по тегам