addEventListener против onclick

704

Какая разница между addEventListenerа onclick?

var h = document.getElementById("a");
h.onclick = dothing1;
h.addEventListener("click", dothing2);

Приведенный выше код находится вместе в отдельном файле .js, и они оба работают отлично.

Уильям Шам
источник

Ответы:

956

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

Прослушиватели событий (addEventListener и IE attachEvent)

В более ранних версиях Internet Explorer JavaScript реализован не так, как в большинстве других браузеров. В версиях менее 9 вы используете метод attachEvent[ doc ], например так:

element.attachEvent('onclick', function() { /* do stuff here*/ });

В большинстве других браузеров (включая IE 9 и выше) вы используете addEventListener[ doc ], например так:

element.addEventListener('click', function() { /* do stuff here*/ }, false);

Используя этот подход ( события DOM уровня 2 ), вы можете прикрепить теоретически неограниченное количество событий к любому отдельному элементу. Единственным практическим ограничением является память на стороне клиента и другие проблемы производительности, которые различны для каждого браузера.

Приведенные выше примеры представляют собой анонимную функцию [ doc ]. Вы также можете добавить прослушиватель событий, используя ссылку на функцию [ doc ] или замыкание [ doc ]:

var myFunctionReference = function() { /* do stuff here*/ }

element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);

Еще одной важной особенностью addEventListenerявляется последний параметр, который контролирует реакцию слушателя на всплывающие события [ doc ]. Я передавал false в примерах, что является стандартным для, вероятно, 95% случаев использования. Не существует эквивалентного аргумента для attachEventили при использовании встроенных событий.

Встроенные события (свойство HTML onclick = "" и element.onclick)

Во всех браузерах, поддерживающих javascript, вы можете встроить прослушиватель событий, то есть прямо в HTML-код. Вы, наверное, видели это:

<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>

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

Другой метод, который вы упоминаете:

element.onclick = function () { /*do stuff here */ };

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

Существенным недостатком встроенных событий является то, что в отличие от прослушивателей событий, описанных выше, вам может быть назначено только одно встроенное событие. Встроенные события сохраняются как атрибут / свойство элемента [ doc ], что означает, что его можно перезаписать.

Используя пример <a>из HTML выше:

var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };

... когда вы щелкнете по элементу, вы увидите только «Сделал материал № 2» - вы перезаписали первое присвоенное onclickсвойство вторым значением, а также перезаписали оригинальное встроенное onclickсвойство HTML . Проверьте это здесь: http://jsfiddle.net/jpgah/ .

Вообще говоря, не используйте встроенные события . Для этого могут быть конкретные варианты использования, но если вы не уверены на 100%, что у вас есть этот вариант использования, то вы не должны и не должны использовать встроенные события.

Современный Javascript (угловой и тому подобное)

С тех пор как этот ответ был первоначально опубликован, фреймворки javascript, такие как Angular, стали намного популярнее. Такой код вы увидите в шаблоне Angular:

<button (click)="doSomething()">Do Something</button>

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

Какой лучше?

Вопрос заключается в совместимости и необходимости браузера. Вам нужно прикрепить более одного события к элементу? Будете ли вы в будущем? Скорее всего, вы будете. attachEvent и addEventListener необходимы. Если нет, то встроенное событие может показаться, что они справятся с задачей, но вам гораздо лучше подготовиться к будущему, которое, хотя и может показаться маловероятным, по крайней мере, предсказуемо. Есть шанс, что вам придется перейти к слушателям событий на основе JS, так что вы можете просто начать там. Не используйте встроенные события.

jQuery и другие инфраструктуры javascript инкапсулируют различные реализации браузером событий DOM уровня 2 в общих моделях, так что вы можете писать кросс-браузерный совместимый код, не беспокоясь об истории IE как мятежника. Тот же код с jQuery, все кросс-браузерные и готовые к работе:

$(element).on('click', function () { /* do stuff */ });

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

function addEvent(element, evnt, funct){
  if (element.attachEvent)
   return element.attachEvent('on'+evnt, funct);
  else
   return element.addEventListener(evnt, funct, false);
}

// example
addEvent(
    document.getElementById('myElement'),
    'click',
    function () { alert('hi!'); }
);

Попробуйте это: http://jsfiddle.net/bmArj/

Принимая все это во внимание, если только сценарий, который вы просматриваете, не учитывает различия браузера каким-либо иным образом (в коде, не показанном в вашем вопросе), используемая часть addEventListenerне будет работать в версиях IE менее 9.

Документация и сопутствующее чтение

Крис Бейкер
источник
14
извините за удар, но просто хотел дать сокращенную версию вашей функции (fiddle: jsfiddle.net/bmArj/153 ) -function addEvent(element, myEvent, fnc) { return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false)); }
Дерик
10
@Gaurav_soni Нет. Имя функции и весь код, который она содержит, уже представлены в файле javascript, который находится в открытом тексте. Любой может открыть веб-консоль и выполнить или манипулировать любым JavaScript. Если ваш javascript содержит что-либо, что может представлять угрозу безопасности, если оно открыто для общественности, то у вас есть серьезная проблема, потому что оно уже открыто для общественности.
Крис Бейкер
4
Пока мы сокращаем этот алгоритм, мы могли бы пройти весь путь: function addEvent(e,n,f){return e.attachEvent?e.attachEvent('on'+n,f):e.addEventListener(n,f,!!0)}<< При 98 символах этот более чем на 40% меньше!
Тревор
3
@Trevor Из любопытства, почему !! 0? Почему нет! 1 или просто 0?
Крис Бейкер
2
@AdrianMoisa Этот ответ был написан в то время, когда AngularJS был новинкой на подъеме, и обычной практикой по-прежнему было «прогрессивное улучшение» - то есть написание HTML-документа таким образом, чтобы он работал с javascript или без него. С этой точки зрения связывание событий из javascript будет наилучшей практикой. В настоящее время я не думаю, что многие люди беспокоятся о прогрессивном улучшении, особенно если не учитывать распространенность таких вещей, как Angular. До сих пор существует некоторое разделение проблем по поводу встроенных событий (без использования Angular), но это скорее стиль, чем сущность.
Крис Бейкер,
193

Разницу вы можете увидеть, если у вас есть еще пара функций:

var h = document.getElementById('a');
h.onclick = doThing_1;
h.onclick = doThing_2;

h.addEventListener('click', doThing_3);
h.addEventListener('click', doThing_4);

Функции 2, 3 и 4 работают, а 1 - нет. Это связано с тем, addEventListenerчто не перезаписывает существующие обработчики событий, а onclickпереопределяет любые существующие onclick = fnобработчики событий.

Другое существенное отличие, конечно, заключается в том, что onclickон всегда будет работать, тогда как addEventListenerон не работает в Internet Explorer до версии 9. Вы можете использовать аналогичный attachEventнемного отличающимся синтаксисом) в IE <9.

lonesomeday
источник
18
Это очень четкое объяснение! Прямо к делу. Так что, если мне нужно несколько функций для одного события, я застрял с addEventListener, и мне нужно написать больше кода для attachEvent просто для размещения IE.
Уильям Шам
4
2, 3 и 4 должны быть названы dosomething. 1 переопределяется на 2 и никогда не вызывается.
DragonLord
Действительно, очень четкое и точное объяснение. Будь то, что действительно было бы гораздо разумнее назвать функции «doThing_1» и т. Д. (Если вы все еще хотите обслуживать IE <9, см. Ответ Криса.)
Фрэнк Конейн
61

В этом ответе я опишу три метода определения обработчиков событий DOM.

element.addEventListener()

Пример кода:

element.addEventListener() имеет множество преимуществ:

  • Позволяет регистрировать неограниченное количество обработчиков событий и удалять их с помощью element.removeEventListener().
  • Имеет useCaptureпараметр, который указывает, хотите ли вы обрабатывать событие в фазе захвата или всплытия . См .: Невозможно понять атрибут useCapture в addEventListener .
  • Заботится о семантике . По сути, это делает регистрацию обработчиков событий более явной. Для новичка вызов функции делает очевидным, что что- то происходит , тогда как присвоение события какому-либо свойству элемента DOM, по крайней мере, не интуитивно понятно .
  • Позволяет разделить структуру документа (HTML) и логику (JavaScript) . В крошечных веб-приложениях это может не иметь значения, но это имеет значение для любого более крупного проекта. Гораздо проще поддерживать проект, который разделяет структуру и логику, чем проект, который этого не делает.
  • Устраняет путаницу с правильными именами событий. Из-за использования встроенных прослушивателей событий или назначения прослушивателей событий .oneventсвойствам элементов DOM многие неопытные программисты JavaScript считают, что имя события, например, onclickили onload. onэто не часть названия события . Правильные имена событий - это clickи load, и именно так передаются имена событий .addEventListener().
  • Работает практически во всех браузерах . Если вам все еще нужно поддерживать IE <= 8, вы можете использовать полифилл из MDN .

element.onevent = function() {}(например onclick, onload)

Пример кода:

Это был способ зарегистрировать обработчики событий в DOM 0. Теперь не рекомендуется, потому что:

  • Позволяет зарегистрировать только один обработчик событий. Кроме того, удаление назначенного обработчика не является интуитивно понятным, поскольку для удаления обработчика событий, назначенного с помощью этого метода, необходимо вернуть oneventсвойство обратно в его начальное состояние (т.е. null).
  • Не отвечает на ошибки соответственно. Например, если вы по ошибке назначите строку window.onload, например:, window.onload = "test";она не выдаст никаких ошибок. Ваш код не будет работать, и было бы очень сложно выяснить, почему. .addEventListener()однако, выдает ошибку (по крайней мере, в Firefox): TypeError: Аргумент 2 из EventTarget.addEventListener не является объектом .
  • Не предоставляет способ выбора, хотите ли вы обрабатывать событие в фазе захвата или всплытия.

Встроенные обработчики событий ( oneventатрибут HTML)

Пример кода:

Точно так же element.onevent, теперь это не рекомендуется. Помимо проблем, которые element.oneventесть, это:

  • Это потенциальная проблема безопасности , потому что это делает XSS намного более вредным. В настоящее время веб-сайты должны отправлять надлежащий Content-Security-Policyзаголовок HTTP, чтобы блокировать встроенные сценарии и разрешать внешние сценарии только из доверенных доменов. Посмотрите, как работает Политика безопасности контента?
  • Не разделяет структуру документа и логику .
  • Если вы генерируете свою страницу с помощью серверного скрипта и, например, генерируете сотню ссылок, каждая с одним и тем же встроенным обработчиком событий, ваш код будет намного длиннее, чем если бы обработчик событий был определен только один раз. Это означает, что клиент должен будет загружать больше контента, и в результате ваш сайт будет работать медленнее.

Смотрите также

Михал Перлаковский
источник
22

Хотя onclickработает во всех браузерах, addEventListenerне работает в более старых версиях Internet Explorer, который использует attachEventвместо этого.

Недостатком onclickявляется то, что может быть только один обработчик событий, в то время как два других будут запускать все зарегистрированные обратные вызовы.

Magnar
источник
12

Насколько я знаю, событие загрузки DOM все еще работает очень ограниченно. Это означает , что он будет стрелять только для window object, imagesи <script>элементы , например. То же самое касается прямого onloadназначения. Между этими двумя нет технической разницы. Вероятно, .onload =имеет лучшую кросс-браузерную доступность.

Тем не менее, вы не можете назначить load eventa <div>или <span>элемент или еще много чего.

JANDY
источник
9

Резюме:

  1. addEventListenerМожно добавить несколько событий, тогда как с onclickэтим не может быть сделано.
  2. onclickможет быть добавлен как HTMLатрибут, тогда как addEventListenerможет быть добавлен только внутри <script>элементов.
  3. addEventListener может принять третий аргумент, который может остановить распространение события.

Оба могут быть использованы для обработки событий. Тем не менее, addEventListenerдолжен быть предпочтительным выбором, так как он может делать все onclick , и многое другое. Не используйте inline onclickкак атрибуты HTML, так как это смешивает JavaScript и HTML, что является плохой практикой. Это делает код менее понятным.

Виллем ван дер Веен
источник
И как в основном осуществляется таргетирование элементов? Я имею в виду, что лично я не собираюсь использовать встроенные onclickобработчики, опасаясь смеха в комнате - но обычно события в последние годы связаны гораздо хуже и менее критично. Такие классы, как js-link, js-form-validationили атрибуты данных с data-jspackage="init"ничем не лучше ... И как часто вы на самом деле используете всплывающие события? Я лично хотел бы иметь возможность написать обработчик, не проверяя, действительно ли цель соответствует моему элементу - или необходимость останавливать распространение в нескольких местах из-за случайных ошибок.
Христоффер Бубах
3

Одна деталь не было замечено еще: современные настольные браузеры рассматривают различные нажатия кнопок , чтобы быть «щелчки» для AddEventListener('click'и onclickпо умолчанию.

  • На Chrome 42 и IE11, onclickи AddEventListenerнажмите огонь на левой и средней кнопкой мыши.
  • В Firefox 38 onclickсрабатывает только при щелчке левой кнопкой мыши, а при AddEventListenerнажатии левой, средней и правой щелчков.

Кроме того, поведение среднего щелчка во всех браузерах очень противоречиво, когда задействованы курсоры прокрутки:

  • В Firefox события среднего щелчка всегда запускаются.
  • В Chrome они не будут срабатывать, если средний щелчок открывает или закрывает курсор прокрутки.
  • В IE они запускаются при закрытии курсора прокрутки, но не при его открытии.

Стоит также отметить, что события «щелчка» для любого HTML-элемента с возможностью выбора с клавиатуры, такие как inputстрельба по пробелу или ввод, когда элемент выбран.

Гость
источник
2

Javascript имеет тенденцию смешивать все в объекты, и это может сбить с толку. Все в одном - это способ JavaScript.

По сути, onclick - это атрибут HTML. И наоборот, addEventListener - это метод объекта DOM, представляющий элемент HTML.

В объектах JavaScript метод - это просто свойство, которое имеет функцию в качестве значения и работает с объектом, к которому он присоединен (используя это, например).

В JavaScript в качестве HTML-элемента, представленного DOM, его атрибуты будут сопоставлены с его свойствами.

Это то, где люди путаются, потому что JavaScript объединяет все в один контейнер или пространство имен без слоя косвенности.

В обычной компоновке OO (которая, по крайней мере, объединяет пространство имен свойств / методов), вы могли бы иметь что-то вроде:

domElement.addEventListener // Object(Method)
domElement.attributes.onload // Object(Property(Object(Property(String))))

Существуют варианты, например, он может использовать метод получения / установки для onload или HashMap для атрибутов, но в конечном итоге это будет выглядеть так. JavaScript устранил этот слой косвенности в ожидании знания того, что есть что среди прочего. Он объединил domElement и атрибуты вместе.

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

Почему это доминирует сегодня? Это быстрее писать, легче учиться и имеет тенденцию просто работать.

Весь смысл загрузки в HTML заключается в том, чтобы в первую очередь предоставить доступ к методу или функциональности addEventListener. Используя его в JS, вы просматриваете HTML, когда можете применять его напрямую.

Гипотетически вы можете сделать свои собственные атрибуты:

$('[myclick]').each(function(i, v) {
     v.addEventListener('click', function() {
         eval(v.myclick); // eval($(v).attr('myclick'));
     });
});

То, что делает JS, немного отличается от этого.

Вы можете приравнять его к чему-то вроде (для каждого созданного элемента):

element.addEventListener('click', function() {
    switch(typeof element.onclick) {
          case 'string':eval(element.onclick);break;
          case 'function':element.onclick();break;
     }
});

Фактические детали реализации, вероятно, будут отличаться в зависимости от ряда тонких изменений, в некоторых случаях они немного различаются, но в этом суть.

Это, возможно, хак совместимости, что вы можете прикрепить функцию к атрибуту on, поскольку по умолчанию все атрибуты являются строками.

jgmjgm
источник
2

Согласно MDN , разница как показано ниже:

addEventListener:

Метод EventTarget.addEventListener () добавляет указанный EventListener-совместимый объект в список прослушивателей событий для указанного типа события в EventTarget, для которого он вызывается. Целью события может быть элемент в документе, сам документ, окно или любой другой объект, который поддерживает события (например, XMLHttpRequest).

по щелчку:

Свойство onclick возвращает код обработчика события click для текущего элемента. При использовании события click для запуска действия также рассмотрите возможность добавления этого же действия к событию keydown, чтобы разрешить использование этого действия теми, кто не использует мышь или сенсорный экран. Синтаксис element.onclick = functionRef; где functionRef - это функция - часто это имя функции, объявленной в другом месте, или выражение функции. См. «Руководство по JavaScript: Функции» для получения подробной информации.

Существует также синтаксическая разница в использовании, как вы видите в следующих кодах:

addEventListener:

// Function to change the content of t2
function modifyText() {
  var t2 = document.getElementById("t2");
  if (t2.firstChild.nodeValue == "three") {
    t2.firstChild.nodeValue = "two";
  } else {
    t2.firstChild.nodeValue = "three";
  }
}

// add event listener to table
var el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);

по щелчку:

function initElement() {
    var p = document.getElementById("foo");
    // NOTE: showAlert(); or showAlert(param); will NOT work here.
    // Must be a reference to a function name, not a function call.
    p.onclick = showAlert;
};

function showAlert(event) {
    alert("onclick Event detected!");
}
Алиреза
источник
1

Если вы не слишком беспокоитесь о поддержке браузера, есть способ перепривязать ссылку «this» в функции, вызываемой событием. Обычно он указывает на элемент, который сгенерировал событие при выполнении функции, что не всегда то, что вы хотите. Сложность состоит в том, чтобы одновременно иметь возможность удалить тот же прослушиватель событий, как показано в этом примере: http://jsfiddle.net/roenbaeck/vBYu3/

/*
    Testing that the function returned from bind is rereferenceable, 
    such that it can be added and removed as an event listener.
*/
function MyImportantCalloutToYou(message, otherMessage) {
    // the following is necessary as calling bind again does 
    // not return the same function, so instead we replace the 
    // original function with the one bound to this instance
    this.swap = this.swap.bind(this); 
    this.element = document.createElement('div');
    this.element.addEventListener('click', this.swap, false);
    document.body.appendChild(this.element);
}
MyImportantCalloutToYou.prototype = {
    element: null,
    swap: function() {
        // now this function can be properly removed 
        this.element.removeEventListener('click', this.swap, false);           
    }
}

Приведенный выше код хорошо работает в Chrome, и, вероятно, есть некоторая шумиха вокруг совместимости «bind» с другими браузерами.

Ларс Рённбек
источник
1

Использование встроенных обработчиков несовместимо с политикой безопасности контента, поэтому этот addEventListenerподход более безопасен с этой точки зрения. Конечно, вы можете включить встроенные обработчики с помощью, unsafe-inlineно, как следует из названия, это небезопасно, поскольку возвращает целые толпы эксплойтов JavaScript, которые предотвращает CSP.

kravietz
источник
1
Примечание: это ограничение безопасности относится только к разработке расширений, а обоснования безопасности, предлагаемые в связанном документе, в основном относятся только к разработке расширений браузера. Тем не менее, в связанном документе, который также справедлив для веб-разработки в целом, есть одна особенность - отделить контент от поведения. Это хорошая практика по всем направлениям.
Крис Бейкер
1

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

подобно

    elm.onclick = myFunctionList
    function myFunctionList(){
      myFunc1();
      myFunc2();
    }

это означает, что нам никогда не придется изменять вызов onclick, просто измените функцию myFunctionList (), чтобы делать то, что мы когда-либо захотим, но это оставляет нас без контроля фаз пузыря / перехвата, поэтому следует избегать для новых браузеров.

на всякий случай кто-нибудь найдет эту ветку в будущем ...

Patrik
источник
1

element.onclick = function () {/ * делать вещи * /}

element.addEventListener ('click', function () {/ * do stuff * /}, false);

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

Основное отличие состоит в том, что onclick - это просто свойство , и, как и все свойства объекта, если вы напишите более одного раза, оно будет перезаписано . Вместо этого с помощью addEventListener () мы можем просто привязать обработчик события к элементу и вызывать его каждый раз, когда нам это нужно, не беспокоясь о каких-либо перезаписанных свойствах. Пример показан здесь,

Попробуйте это: https://jsfiddle.net/fjets5z4/5/

Во-первых, я испытывал желание продолжать использовать onclick, потому что он короче и выглядит проще… и на самом деле так оно и есть. Но я не рекомендую использовать его больше. Это похоже на использование встроенного JavaScript. Использование чего-то подобного - встроенного JavaScript - в настоящее время крайне нежелательно (встроенный CSS тоже не рекомендуется, но это уже другая тема).

Однако функция addEventListener (), несмотря на то, что она стандартна, просто не работает в старых браузерах (Internet Explorer ниже версии 9), и это еще одно большое отличие. Если вам нужно поддерживать эти древние браузеры, вы должны следовать по принципу onclick. Но вы также можете использовать jQuery (или одну из его альтернатив): он в основном упрощает вашу работу и уменьшает различия между браузерами, поэтому может сэкономить вам много времени.

var clickEvent = document.getElementByID("onclick-eg");
var EventListener = document.getElementByID("addEventListener-eg");

clickEvent.onclick = function(){
    window.alert("1 is not called")
}
clickEvent.onclick = function(){
    window.alert("2 is not called")
}

EventListener.addEventListener("click",function(){
    window.alert("1 is called")
})
EventListener.addEventListener("click",function(){
    window.alert("2 is also called")
})
Архам Чоудхури
источник
0

addEventListener позволяет установить несколько обработчиков, но не поддерживается в IE8 или ниже.

IE есть attachEvent, но это не совсем то же самое.

user113716
источник
0

Контекст, на который ссылается 'this'ключевое слово в JavasSript, отличается.

посмотрите на следующий код:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>

</head>
<body>
    <input id="btnSubmit" type="button" value="Submit" />
    <script>
        function disable() {
            this.disabled = true;
        }
        var btnSubmit = document.getElementById('btnSubmit');
        btnSubmit.onclick = disable();
        //btnSubmit.addEventListener('click', disable, false);
    </script>
</body>
</html>

То, что он делает, действительно просто. когда вы нажимаете кнопку, кнопка автоматически отключается.

Сначала, когда вы попытаетесь подключить события таким образом, button.onclick = function(), событие onclick будет вызвано нажатием кнопки, однако кнопка не будет отключена, поскольку нет явной привязки между button.onclick и обработчиком события onclick. Если вы отлаживаете, видите 'this'объект, вы можете видеть, что он ссылается на 'window'объект.

Во-вторых, если вы прокомментируете btnSubmit.onclick = disable();и раскомментируете, //btnSubmit.addEventListener('click', disable, false);вы увидите, что кнопка отключена, потому что таким образом существует явная привязка между событием button.onclick и обработчиком события onclick. Если вы отладки в функции отключения, вы можете увидеть , 'this'относится к , button controlа неwindow .

Это то, что мне не нравится в JavaScript, что является непоследовательностью. Кстати, если вы используете jQuery ( $('#btnSubmit').on('click', disable);), он использует явное связывание.

Larry
источник
8
Вам нужно написать btnSubmit.onclick = disable;(назначить функцию, а не вызывать ее). Тогда в обоих случаях thisбудет ссылаться на элемент кнопки.
Паша
-1

onclick - это, по сути, addEventListener, который специально выполняет функцию при нажатии на элемент. Так что полезно, когда у вас есть кнопка, которая выполняет простые операции, например кнопка калькулятора. addEventlistener может использоваться для множества вещей, таких как выполнение операции, когда загружен DOM или весь контент, похожий на window.onload, но с большим контролем.

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

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

Какой вы используете, я полагаю, будет зависеть от того, что вы хотите. addEventListener для сложных операций и onclick для простых. Я видел, что некоторые проекты не привязывают определенный элемент к элементам и вместо этого реализуют более глобальный список событий, который будет определять, было ли нажатие на кнопку, и выполнять определенные задачи в зависимости от того, что было нажато. Imo, которые потенциально могут привести к проблемам, я бы подумал, и хотя и небольшая, возможно, пустая трата ресурсов, если бы этот обработчик событий должен был обрабатывать каждый щелчок

ThatOneNoob
источник