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

发布于 2024-12-06 00:54:16 字数 346 浏览 1 评论 0原文

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

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

相同数据的路径数量之多简直是荒谬的。这些方法中的一种是否比其他方法优越得多?

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

滴情不沾 2024-12-13 00:54:16

对于这种情况,我将使用 .media ,因为 media 确实是链接元素上的属性。其中每一个都有其用途:

  • ['media'] 使用方括号表示法检索“media”属性值。当您在设计时不知道属性的名称时,请使用方括号表示法。例如,当迭代属性时。
  • .media 检索“media”属性值。大多数情况下我都会使用这个。它提供了对属性值的简洁、直接的访问。
  • .getAttribute('media') 检索“media”属性值。当您想要的属性值不一定是元素上的属性时,请使用此选项。并非所有属性都是属性,也不是所有属性都是属性。
  • .attributes['media'] 检索“media”属性节点。当您需要有关属性的更多信息而不仅仅是其值时,请使用属性集合。例如,属性名称。您还可以轻松地使用它来获取值,因为 .toString() 返回值,但如果您想要的只是值,那么这可能有点过头了。 attributes 集合对于迭代元素的属性也很有用。

I would use .media for this case, since media is indeed a property on the link element. Each of these has its use:

  • ['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 attributes collection is also useful for iterating the attributes of an element.
看春风乍起 2024-12-13 00:54:16

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

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

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

添加更多技术细节,尽管不同的方式在大多数情况下返回相同的方式,但这对于不存在的属性不一定成立。以以下 HTML 为例:。您可以在另一个浏览器中在 测试 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

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

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

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

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

第一次调用返回属性默认值。然后我们看到 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

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

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

设置有效属性的属性还会在 attributes 映射中创建一个条目。

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

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

即使属性的存在无效,也会创建属性,但它不能作为属性使用。

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

对象 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);

节点图仅反映 DOM 的当前状态。它不知道我们通过 getElementsByTagName 接收到的对象 a 的扩展。

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

我希望对最终的 NamedNodeMap 发表评论,因为我想知道 Firefox 的行为是否正确,即丢弃解析中的属性顺序。

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

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

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.

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).

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

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

// 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 null as 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 undefined value.

// 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 attributes map.

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

// 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 a is extended but 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. It is not aware of extension to our object a that we received via 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.

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.

不忘初心 2024-12-13 00:54:16

从功能上来说,它们是平等的。

就性能而言,前两者要优越得多——尽管它们都非常快。请参阅此 JSPerf 测试

实际上,前两个更容易阅读,我个人更喜欢第二个。 (这也快了一根头发。)

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.

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

洋洋洒洒 2024-12-13 00:54:16

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

最后两个选项依赖于 getAttribute()setAttribute(),它们在 IE 中并不总是可靠的。您可以在

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

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 .media version out of all four of your choices as most reliable and most readable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文