Javascript 从 getElementsByTagName() 获取属性的最佳方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7490203/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:28:56  来源:igfitidea点击:

Best method to get attributes from getElementsByTagName()?

javascriptdomattributes

提问by JKirchartz

I'm playing around with getting attributes of a linktag, there seems to be several ways of accessing the attributes:

我正在link尝试获取标签的属性,似乎有几种访问属性的方法:

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

It's bordering on ridiculous how many paths there are to the same data. Is one of these methods far superior to the rest?

有多少条路径可以访问相同的数据,这几乎是荒谬的。这些方法中的一种是否远远优于其他方法?

回答by gilly3

I would use .mediafor this case, since mediais indeed a property on the link element. Each of these has it's use:

我会.media在这种情况下使用,因为media它确实是链接元素上的一个属性。每一个都有它的用途:

  • ['media']:Retrieves the "media" property value using square bracket notation. Use square bracket notation when you don't know the name of the property at design time. For example, when iterating properties.
  • .media:Retrieves the "media" property value. I'd use this in most cases. It provides concise, direct access to the property value.
  • .getAttribute('media'):Retrieves the "media" attribute value. Use this when you want the value of an attribute that is not necessarily a property on the element. Not all attributes are properties and not all properties are attributes.
  • .attributes['media']:Retrieves the "media" attribute node. Use the attributes collection when you need more information about an attribute than just it's value. For example, the attribute name. You can also easily use this to get the value, since .toString()returns the value, but that may be overkill if all you want is the value. The attributescollection is also useful for iterating the attributes of an element.
  • ['media']使用方括号表示法检索“媒体”属性值。如果在设计时不知道属性的名称,请使用方括号表示法。例如,在迭代属性时。
  • .media检索“媒体”属性值。大多数情况下我会使用它。它提供了对属性值的简洁、直接的访问。
  • .getAttribute('media')检索“媒体”属性值。当您想要不一定是元素上的属性的属性值时,请使用此选项。并非所有属性都是属性,也并非所有属性都是属性。
  • .attributes['media']检索“媒体”属性节点。当您需要有关属性的更多信息而不仅仅是其值时,请使用属性集合。例如,属性名称。您也可以轻松地使用它来获取值,因为.toString()返回值,但如果您只想要该值,这可能有点过头了。该attributes集合对于迭代元素的属性也很有用。

回答by Augustus Kling

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

您正在寻找的方法称为getElementsByTagName。它返回一个类似数组的元素列表(不是数组)。

Note that your last sample .attributes['media']does not return a string as the other methods. It returns an attribute node instead.

请注意,您的最后一个示例.attributes['media']不会像其他方法那样返回字符串。它返回一个属性节点。

In theory the ways of accessing the content should be equivalent but browser bugs led to other behavior in reality. It's probably best to use an abstraction layer (a library such as jQuery) to get consistent behavior. If you intend to program without a library the choice depends on your taste however I'd say that going via the attribute node is safest in general.

理论上,访问内容的方式应该是等效的,但实际上浏览器错误会导致其他行为。最好使用抽象层(例如 jQuery 的库)来获得一致的行为。如果您打算在没有库的情况下进行编程,则选择取决于您的喜好,但是我认为通过属性节点通常是最安全的。

To add a bit more technical detail, although the different way return the same ways most of the time this is not necessarily true for non-existent attributes. Take the following HTML as example: <a href='test'>. You can try it yourself in another browser on a test jsFiddle(the output below is from Firefox).

添加更多技术细节,尽管不同的方式在大多数情况下以相同的方式返回,但对于不存在的属性不一定如此。以下面的 HTML 为例:<a href='test'>. 您可以在测试 jsFiddle另一个浏览器中自己尝试(下面的输出来自 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 one time an absolute URI was returned, another time the original value was returned.

请注意,一次返回绝对 URI,另一次返回原始值。

// 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 on page load gets merged into DOM but is not available as property if invalid.

页面加载时存在的所有内容都会合并到 DOM 中,但如果无效则不能作为属性使用。

// 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 returned a properties default value. Then we saw nullas a marker for an inexistent attribute. Lastly we got a so called NamedNodeMap which is something like a mixture of an array and object. Accessing it as an object gave the undefinedvalue.

第一次调用返回了一个属性默认值。然后我们将其null视为不存在属性的标记。最后,我们得到了一个所谓的 NamedNodeMap,它类似于数组和对象的混合体。将它作为一个对象访问给出了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

Attribute becomes available as property, too.

属性也可以作为财产使用。

// 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

Setting property for a valid attribute also creates an entry in attributesmap.

为有效属性设置属性也会在attributes地图中创建一个条目。

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

Property access on a, marker return value and index access on node map.

属性访问a,标记返回值和节点映射上的索引访问。

// 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

Attribute gets created even though its existent is invalid but it is not available as 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 ais extended but DOM is untouched.

对象a已扩展,但 DOM 未受影响。

// 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. It is not aware of extension to our object athat we received via getElementsByTagName.

节点映射仅反映 DOM 的当前状态。它不知道a我们通过getElementsByTagName.

It's important to note that manipulating JavaScript object does not necessarily affect the DOM. The DOM only reflects the things that have been available on parsing plus modification with DOM methods or property modifications (of predefined properties that is). I hope I did not miss any important cases and that the comments have been verbose enough to see what happens.

需要注意的是,操作 JavaScript 对象并不一定会影响 DOM。DOM 仅反映了在解析和使用 DOM 方法或属性修改(即预定义属性)进行修改时可用的内容。我希望我没有错过任何重要的案例,并且评论已经足够详细,可以看到会发生什么。

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

我很感激对最终 NamedNodeMap 的评论,因为我想知道 Firefox 的行为是否正确以丢弃解析中的属性顺序。

回答by cheeken

Functionally, they are equal.

在功能上,它们是平等的。

Performance-wise, the first two are superior by a significant factor - though they are all extremely fast. See this JSPerf test.

在性能方面,前两个在一个重要因素上更胜一筹——尽管它们都非常快。请参阅此 JSPerf 测试

Practically speaking, the first two are easier to read, and my personal preference is the second. (It's also a hair faster.)

实际上,前两个更容易阅读,我个人的喜好是第二个。(它也快了一个头发。)

回答by jfriend00

The first two options are the the same. You can use either. I personally prefer the .mediaversion since I think it reads easier.

前两个选项是相同的。你可以使用。我个人更喜欢这个.media版本,因为我认为它读起来更容易。

The last two options depend upon getAttribute()and setAttribute()which have not always been reliable in IE. You can read a lot more about that in the reference that Matt posted. As such, I prefer the .mediaversion out of all four of your choices as most reliable and most readable.

最后两个选项取决于getAttribute()setAttribute()它并不总是可靠的IE浏览器。您可以在Matt 发布参考资料中阅读更多相关内容。因此,我更喜欢.media您选择的所有四个版本中最可靠和最易读的版本。