Best way to get attributes from getElementsByTagName ()?

I play with link tag attributes, there seem to be several ways to access attributes:

 document.getElementsByTagName("link")[0]['media'] document.getElementsByTagName("link")[0].media document.getElementsByTagName("link")[0].getAttribute('media') document.getElementsByTagName("link")[0].attributes['media'] 

This borders on an absurd number of paths to the same data. Is one of these methods far superior to the rest?

+6
source share
4 answers

I would use .media for this case, since media indeed a property of the link element. Each of them uses:

  • ['media'] : Gets the value of the "media" property using square notation. Use square notation when you do not know the name of the object during development. For example, with repeated properties.
  • .media : Retrieves the value of the media property. I would use this in most cases. It provides short, direct access to the property value.
  • .getAttribute('media') : Retrieves the value of the "media" attribute. Use this when you want an attribute value to not necessarily be a property of an element. Not all attributes are properties, and not all properties are attributes.
  • .attributes['media'] : Retrieves the attribute "media" node. Use the attribute collection when you need more information about an attribute, not just a value. For example, the name of the attribute. You can also easily use this to get a value, since .toString() returns a value, but it might be redundant if all you want is a value. The attributes collection is also useful for iterating over element attributes .
+10
source

The method you are looking for is called getElementsByTagName . It returns an array of list items (which is not an array).

Note that your last .attributes['media'] sample does not return a string as other methods. Instead, it returns the node attribute.

Theoretically, ways to access content should be equivalent, but browser errors have led to other behaviors in reality. It is probably best to use an abstraction layer (library such as jQuery) to get consistent behavior. If you intend to program without a library, the choice depends on your taste, however I would say that passing through the node attribute is the safest in general.

To add a little more detailed technical information, although a different method returns the same paths most of the time, this is not necessarily true for non-existent attributes. Take the following HTML as an example: <a href='test'> . You can try it in another browser jsFiddle test (exit below from Firefox).

 // Get reference to element var a = document.getElementsByTagName('a')[0]; // Existent attributes console.log(a.href); // String: http://fiddle.jshell.net/_display/test console.log(a.getAttribute('href')); // String: test console.log(a.attributes['href']); // Attribute node: href 

Note that once an absolute URI was received, and at another time, the original value was returned.

 // Existent invalid attributes console.log(a.other); // undefined console.log(a.getAttribute('other')); // String: thing console.log(a.attributes['other']); // Attribute node: other 

Everything that exists when the page loads is combined in the DOM, but is not available as a property if it is not valid.

 // Inexistent but valid attributes console.log(a.title); // Empty string console.log(a.getAttribute('title')); // null console.log(a.attributes['title']); // undefined 

The first call returns the default value for the property. Then we saw null as a marker for a nonexistent attribute. Finally, we got the so-called NamedNodeMap, which is something like a mixture of an array and an object. Access to it as an object gave the value undefined .

 // Creating attributes a.setAttribute('title', 'test title'); console.log(a.title); // String: test title console.log(a.getAttribute('title')); // String: test title console.log(a.attributes['title']); // Attribute node: title 

An attribute also becomes available as a property.

 // Creating "attributes" by using property a.rel = 'test rel'; console.log(a.rel); // String: test rel console.log(a.getAttribute('rel')); // String: test rel console.log(a.attributes['rel']); // Attribute node: rel 

The property property for a valid attribute also creates an entry in the attributes map.

 // Inexistent invalid attributes console.log(a.dummyInvention); // undefined console.log(a.getAttribute('dummyInvention')); // null console.log(a.attributes['dummyInvention']); // undefined 

Access to properties on a , the return value of the marker, and access to the index on the map node.

 // Creating invalid attributes via setAttribute a.setAttribute('title2', 'test title2'); console.log(a.title2); // undefined console.log(a.getAttribute('title2')); // String: test title2 console.log(a.attributes['title2']); // Attribute node: title2 

An attribute is created, although its existing one is invalid, but it is not available as a property.

 // Creating invalid "attributes" via property a.title3 = 'test title3'; console.log(a.title3); // String: test title3 console.log(a.getAttribute('title3')); // null console.log(a.attributes['title3']); // undefined 

Object a extended, but the DOM is untouched.

 // NamedNodeMap of length 4 and indexes other, href, title, rel, title2 (valid attributes or result of setAttribute in order of creation except those from parsing) console.log(a.attributes); 

The node map only reflects the current state of the DOM. He does not know the extension of our object a , which we received through getElementsByTagName .

It is important to note that manipulating a JavaScript object does not necessarily affect the DOM. The DOM only reflects what was available during parsing plus a modification using DOM methods or property modifications (predefined properties that are). I hope I have not missed any important things and that the comments were detailed enough to see what was happening.

I would appreciate a comment on the final NamedNodeMap because I would like to know if Firefox's behavior is correct in order to reverse the order of the attributes during parsing.

+3
source

Functionally, they are equal.

In terms of performance, the first two are superior to a significant factor - although they are all very fast. See this JSPerf test .

In fact, the first two are easier to read, and my personal preference is the second. (This is also hair faster.)

+1
source

The first two options are the same. You can also use. I personally prefer the .media version, as I think it is easier to read.

The last two parameters depend on getAttribute() and setAttribute() , which were not always reliable in IE. You can read a lot more about this in the link Matt posted . Thus, I prefer the .media version of all four of your options, as the most reliable and most readable.

0
source

Source: https://habr.com/ru/post/897709/


All Articles