简体   繁体   中英

Which Event.target Property Should I Use?

When finding which element an event originated from is there an event.target property that works best?

Take this block of code for example:

document.addEventListener("keypress", function (event) {

    if (event.target.className == "input-field")
        callFunctionName();

}, false);

This same piece of code works whether the if statement contains event.target.nodeName == "INPUT" , event.target.dataset.field == "input" , etc.

Is there any reason why one of these properties should be used over the others or maybe why one is worse than the rest?

It depends on how specific you need to be. In particular, your current:

event.target.className == "input-field"

is not particularly flexible - this will work only if the element has that class , input-field , and that class only. What if, later, you figure out that you want to add another class to that element, for styling or something? Then, the above test will fail, and you'll have to go back and fix it.

This same piece of code works whether the if statement contains event.target.nodeName == "INPUT"

This will match any input field on the page, which may well be undesirable - what if additional HTML you add later happens to include an <input> that you don't want to trigger this handler? Then, you'll have to come back and fix this.

event.target.dataset.field == "input"

This will result in the handler being triggered for any element with data-field="input" . While perhaps unlikely, what if such an element is added to the HTML later, one that you don't want this listener to be connected to? Then, again, you'll have to come back and fix it.

It's usually a good idea to be as specific as possible when targeting elements. You can do this with Element.prototype.matches - pass it a selector string (selector strings are very flexible), and it will return a boolean indicating whether the selector string matches the element:

if (event.target.matches('input.input-field[data-field="input"]')) {
  callFunctionName();
}

No valid answer for that, depends of your case.

For example:

If you want to do only with one target, you will use ID.

If you want to do with inputs type text you will use e.target.type

If you want to do with inputs than can be selects or inputs but have the same class in common you will use className..

Think what you want and this will be the correct answer!

The most standard and reliable way to know what element triggered an event is with event.target .

What property(ies) you choose to access from that object really depends on what aspect of that object you are interested in.

nodeName always returns an all caps string containing the name of the HTML element (the tag name, not the element's name attribute or its id ).

 console.log(document.getElementById("test1").nodeName); // SELECT console.log(document.getElementById("test2").nodeName); // OPTION console.log(document.getElementById("test3").nodeName); // OPTION 
 <select id="test1"> <option id="test2">Choice 1</option> <option id="test3">Choice 2</option> </select> 

dataset is used for a completely different reason. It returns a data attribute value for the data attribute specified after .dataset . The only way this API would be comparable to event.target.nodeName would be if you had an element similar to this:

<input type="text" data-field="input">

which is unlikely. Here's an example of how values of data-* attributes in your HTML elements can be retrieved in JavaScript.

 console.log(document.getElementById("test1").dataset.policyType); // Home 
 <div id="test1" data-policy-type="Homeowners">Policy Number: 1234546</div> 

The two APIs each serve their purpose, but they are not interchangeable.

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