简体   繁体   中英

What is the difference between HTML Event Attributes and Assign Events Using the HTML DOM?

HTML Event Attributes:

<button onclick="displayDate()">Try it</button>

Assign Events Using the HTML DOM:

<script>

document.getElementById("myBtn").onclick = function(){ displayDate() };

</script>

What is the difference between these two ? Any advantages in using (Assign Events Using the HTML DOM) ?

Thanks

There are very big differences.

Event handlers that are set up via HTML event attributes were the first way we did event handling - - before there was a DOM. This way of setting up events became known as DOM Level 0 (as in, the de facto standard before there was a standard). When this was the way to do it (circa 1995), it was fine, because we had no other choice. But, the way the attribute value was turned into event handling code was handled like this:

The HTML element has an event attribute declared on it and that attribute has a value that is the JavaScript code that should be executed when the event occurs:

 <input type="button" onclick="alert('You clicked me!')" value="Click me">

Notice that the value of onclick isn't a function reference, just loose code to run.

This is actually implemented by the browser by creating a function in the Global scope that acts as a wrapper for the supplied code. We can see that here:

 // Output the value of the onclick property. // Note the value supplied in the HTML // is wrapped in a function that we didn't create alert(document.querySelector("input").onclick);
 <input type="button" onclick="alert('You clicked me!')" value="Click me">

Because of this automatic wrapping of the attribute value in a Global wrapper function, non-intuitive things often happened like this:

 function foo(){ // This function is invoked by clicking the HTML input element // so, we may reasonably expect that "this" would reference that // element. But, as you'll see, it doesn't. alert("You clicked the " + this.nodeName + " element."); }
 <input type="button" onclick="foo()" value="Click me">

The above reports undefined because in actuality, this in that context is referring to the Global window object, which doesn't have a nodeName property. But, if you didn't know about the Global wrapper (and why would you), this would be very confusing because this used by a DOM event handler almost always references the DOM element that caused the event to fire.

When the DOM Level 1 Event Handling specification came out (1998), a new way of configuring events came about as well. We now had objects that represented the HTML elements and each object had properties that mapped to the attributes of the element. For this reason many people (up to this very day) still believe that working with attributes or object properties is largely the same thing. But, there are important differences (which I've written about in this other answer of mine: see second half of answer) as attributes are used to set values, which can affect state, but properties are used to override attributes and set state.

So, with DOM event handling, we'd do the following, which you will see, sets up the event callback, not as loose code to be executed, but by storing a reference to a function to be invoked when the event occurs. Because we supply the function, it has the scope of the DOM object we store it with and we no longer need to wrap loose commands with a Global. This causes this binding to work as expected:

 // Just a reference to a function is used with event // properties. Not "loose" code. And, because the function // is actually being stored with the DOM element, this binding // works as expected. document.querySelector("input").onclick = foo; function foo(){ // This function is invoked by clicking the HTML input element // so, we may reasonably expect that "this" would reference that // element. But, as you'll see, it doesn't. alert("You clicked the " + this.nodeName + " element."); }
 <input type="button" value="Click me">

The additional benefit of DOM Event handling was that we kept the JavaScript stuff separate from the HTML stuff (ie. separation of concerns). This was a benefit, but not the driving force for the change.

Now, having explained the differences between those two mechanisms for registering events, the story isn't complete. There is still an problem with DOM event properties in that if you wanted to set up multiple event handlers, you didn't have a clean way to do that since you can only store one function reference in a given property. So, with modern event handling, we use .addEventListener() , which allows us to register as many event callbacks with an event that we want and we get the added benefit of knowing that the callbacks we register will be invoked in the order that we registered them.

 // Register an event listener: document.querySelector("input").addEventListener("click", foo1); // Register more event listeners: document.querySelector("input").addEventListener("click", foo3); document.querySelector("input").addEventListener("click", foo2); function foo1(){ console.log("Hello from foo1"); } function foo2(){ console.log("Hello from foo2"); } function foo3(){ console.log("Hello from foo3"); }
 <input type="button" value="Click me">

The difference (or, rather, connection) is described in clause 6.1.5 Events of the HTML5 specification. The basic difference is that an event attribute like onclick contains JavaScript code (typically, a function invocation) that is executed as such, whereas the click property of an element node is a reference to a function definition. If you use, say, onclick="displayDate()" in HTML source and then inspect the DOM in a browser's developer tools, you'll see that the connection is more complicated in principle.

The practical difference is large a matter of opinion and coding style. Using the onclick attribute makes it immediately obvious to anyone reading the HTML source code that an event handler is present. This may also be disadvantage, when reading the HTML code primarily as structured data. But there is a definite technical advantage when several elements need to have the same event handler, eg when you want a click on any link trigger some handler (before or instead of normal following link operation). Using JavaScript, you can have a loop that assigns the same function to all links, as opposite to copying the same onclick attribute in HTML markup.

The advantage is you don't mess js code with html, it permits you to separate programming layers. This renders your code cleaner and less prone to bugs. A practice that complies with web accessibility rules and good programming foundations.

There is no difference. OnClick it's the same event.

If you want to call different methods , with javascript you can manipulate what to do when OnClick it's raised.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM