Addeventlistener VS Onclick

addEventListener vs onclick

Both are correct, but none of them are "best" per se, and there may be a reason the developer chose to use both approaches.

Event Listeners (addEventListener and IE's attachEvent)

Earlier versions of Internet Explorer implement JavaScript differently from pretty much every other browser. With versions less than 9, you use the attachEvent[doc] method, like this:

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

In most other browsers (including IE 9 and above), you use addEventListener[doc], like this:

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

Using this approach (DOM Level 2 events), you can attach a theoretically unlimited number of events to any single element. The only practical limitation is client-side memory and other performance concerns, which are different for each browser.

The examples above represent using an anonymous function[doc]. You can also add an event listener using a function reference[doc] or a closure[doc]:

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

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

Another important feature of addEventListener is the final parameter, which controls how the listener reacts to bubbling events[doc]. I've been passing false in the examples, which is standard for probably 95% of use cases. There is no equivalent argument for attachEvent, or when using inline events.

Inline events (HTML onclick="" property and element.onclick)

In all browsers that support javascript, you can put an event listener inline, meaning right in the HTML code. You've probably seen this:

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

Most experienced developers shun this method, but it does get the job done; it is simple and direct. You may not use closures or anonymous functions here (though the handler itself is an anonymous function of sorts), and your control of scope is limited.

The other method you mention:

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

... is the equivalent of inline javascript except that you have more control of the scope (since you're writing a script rather than HTML) and can use anonymous functions, function references, and/or closures.

The significant drawback with inline events is that unlike event listeners described above, you may only have one inline event assigned. Inline events are stored as an attribute/property of the element[doc], meaning that it can be overwritten.

Using the example <a> from the HTML above:

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

... when you clicked the element, you'd only see "Did stuff #2" - you overwrote the first assigned of the onclick property with the second value, and you overwrote the original inline HTML onclick property too. Check it out here: http://jsfiddle.net/jpgah/.

Broadly speaking, do not use inline events. There may be specific use cases for it, but if you are not 100% sure you have that use case, then you do not and should not use inline events.

Modern Javascript (Angular and the like)

Since this answer was originally posted, javascript frameworks like Angular have become far more popular. You will see code like this in an Angular template:

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

This looks like an inline event, but it isn't. This type of template will be transpiled into more complex code which uses event listeners behind the scenes. Everything I've written about events here still applies, but you are removed from the nitty gritty by at least one layer. You should understand the nuts and bolts, but if your modern JS framework best practices involve writing this kind of code in a template, don't feel like you're using an inline event -- you aren't.

Which is Best?

The question is a matter of browser compatibility and necessity. Do you need to attach more than one event to an element? Will you in the future? Odds are, you will. attachEvent and addEventListener are necessary. If not, an inline event may seem like they'd do the trick, but you're much better served preparing for a future that, though it may seem unlikely, is predictable at least. There is a chance you'll have to move to JS-based event listeners, so you may as well just start there. Don't use inline events.

jQuery and other javascript frameworks encapsulate the different browser implementations of DOM level 2 events in generic models so you can write cross-browser compliant code without having to worry about IE's history as a rebel. Same code with jQuery, all cross-browser and ready to rock:

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

Don't run out and get a framework just for this one thing, though. You can easily roll your own little utility to take care of the older browsers:

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!'); }
);

Try it: http://jsfiddle.net/bmArj/

Taking all of that into consideration, unless the script you're looking at took the browser differences into account some other way (in code not shown in your question), the part using addEventListener would not work in IE versions less than 9.

Documentation and Related Reading

  • W3 HTML specification, element Event Handler Attributes
  • element.addEventListener on MDN
  • element.attachEvent on MSDN
  • Jquery.on
  • quirksmode blog "Introduction to Events"
  • CDN-hosted javascript libraries at Google

What is the difference between .onclick and .addEventListener( click , function())?

Here are what I found for your questions:
addEventListner:

  • Can add multiple events to a particular element.
  • Can take a third argument that can control the event propagation.
  • Can only be added within elements or in external JavaScript file.

On the other hand - onclick:

  • Can add only a single event to an element, and it is basically a property, so gets overwritten.
  • Event propagation cannot be controlled by onclick.
  • Can be added as an HTML attribute also.

Also, you can read more about the difference Here

What is the difference between calling addEventListener() vs. adding the event + function into the HTML tag

  1. addEventListener can add multiple events, whereas with onclick this cannot be done.
  2. onclick can be added as an HTML attribute, whereas an addEventListener can only be added within <script> elements.
  3. addEventListener can take a third argument that can stop the event propagation.

Both can be used to handle events. However, addEventListener should be the preferred choice since it can do everything onclick does and more. Don't use inline onclick as HTML attributes as this mixes up the javascript and the HTML which is a bad practice. It makes the code less maintainable.

Is it more efficient to use addEventListener, or onclick for performance?

addEventListner will be faster when compared to onclick. You can check the below link for performance details by running tests.

http://jsperf.com/click-vs-addeventlistener/9

For more details on using those, you can check the following link.

addEventListener vs onclick

What is the order of inline onclick vs addeventlistener and why?

The answer is, yes, this is actually covered in the specification but not the ECMAScript spec per se, which only strictly deals with ECMAScript independent of implementation.

Firstly, the ordering of DOM events. I refer you to this relevent SO question.

Are event handlers in JavaScript called in order?

As this states, previously it was unspecifed but as of the DOM level 3 spec it does specifically state they should be executed in the order that they are registered.

But what about inline event handlers defined like in your example?

For this we can turn to the HTML 5 spec which says:

An event handler content attribute is a content attribute for a specific event handler. The name of the content attribute is the same as the name of the event handler.

[...]

When an event handler H of an element or object T implementing the EventTarget interface is first set to a non-null value, the user agent must append an event listener to the list of event listeners associated with T with type set to the event handler event type corresponding to H and callback set to the event handler processing algorithm defined below.

Unpacking this and the subsequent notes a bit the key things to take away here are:

  • The act of adding an 'event handler content attribute' (e.g. your onclick attribute) will cause an event listener to be added to the list referred to earlier in the DOM spec.
  • What is actually happening behind the scenes is that this event listener is not strictly the code you specified in the onclick attribute but an internal event handler processing algorithm for evaluating the attribute and executing the appropriate callback.
  • Importantly when the attribute changes or is set to null then the event listener, and it's position in the list, is not changed. Only the outcome of the event handler processing algorithm is changed (because you have changed the input).

This might be a bit confusing. It might help to read and digest the notes on the spec yourself, but I will also try to cover the key implications below.

Firstly, yes, the behaviour you see is effectively defined by the spec as a logical result of what the spec tells us. When a document is being parsed and encounters an inline event handler attribute then this internal algorithm is added to the list of event listeners immediately. According to the spec then this will mean that the first event listener will be the one corresponding to your event handler attribute. Since this has to have been set before any calls to addEventListener since it wouldn't be possible to call addEventListener on a element that didn't exist then. In these circumstances it will always execute first.

The interesting stuff happens when we start messing with the inline attribute after the initial parsing. Here's an example from the HTML5 spec itself that appears right after the bit I quoted above:

EXAMPLE 8

This example demonstrates the order in which event listeners are invoked. If the button in this example is clicked by the user, the page will show four alerts, with the text "ONE", "TWO", "THREE", and "FOUR" respectively.

 <button id='test'>Start Demo</button>
<script>
var button = document.getElementById('test');
button.addEventListener('click', function () { alert('ONE') }, false);
button.setAttribute('onclick', "alert('NOT CALLED')"); // event handler listener is registered here
button.addEventListener('click', function () { alert('THREE') }, false);
button.onclick = function () { alert('TWO'); };
button.addEventListener('click', function () { alert('FOUR') }, false);
</script>

As we can see then the initial value of the onclick attribute is overriden, but the new onclick handler still executes between the first and the second listener set with addEventListener. The reason for this is that the inline event handler will effectively always be in the list of listeners at the same point it was when it was first added to the element. This is because technically, as stated earlier, the actual event listener is not the callback we have specified in the attribute content, but an internal algorithm that takes the attribute contents as it's input.

I have created a JSFiddle to test this is the case and I can confirm this is the behaviour I see in both Firefox and Chrome.


So to summarise, in practical terms:

  1. Event handler attributes, encountered in a documents source when first loading, will always execute first since they could not have had an event listener added before.
  2. For event handler attributes added later with e.g setAttribute, then they will respect the order in which they were added respective to earlier and later calls to addEventListener.
  3. However changing or unsetting the value of an event handler attribute will not change it's position in the list of event listeners.

Hope that clears things up!

Is React onClick more like a JavaScript addEventListener than like a standard JavaScript onclick attribute?

Almost, it looks like this:

// mapEventToComponent implemented by React
document.getElementById("root").addEventListener("click", mapEventToComponent,...);

In React, event handlers (like onClick handler) are SyntheticEvent instances.

It helps achieve high performance by using event delegation. React attaches a single event listener to root of the document (and not to nodes themselves), when an event called, React maps it to the component.

Check it yourself!

const Component = () => {
return <button onClick={() => console.log("hello")}>Click</button>;
};

Edit Synthetic Event

  1. Open dev tools
  2. Fire the event to see if it's working.
  3. Go to Event Listeners tab.
  4. Check to which element all events attached.
  5. Remove the click listeners from #root element.

Sample Image

using addEventListener or onclick method for executing a function when someone clicks on it?

The main difference is that onclick is just a property. Like all object properties, you may have one inline event assigned. If you write more than once, it will be overwritten.
addEventListener() on the other hand, can have multiple event handlers applied to the same element. It doesn’t overwrite other present event handlers.

heres a good link
https://medium.com/@tshlosberg/addeventlistener-vs-onclick-which-one-should-you-use-47550d7e7487



Related Topics



Leave a reply



Submit