Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从getElementsByTagName()获取属性的最佳方法是什么?_Javascript_Dom_Attributes - Fatal编程技术网

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

Javascript 从getElementsByTagName()获取属性的最佳方法是什么?,javascript,dom,attributes,Javascript,Dom,Attributes,我正在尝试获取链接标记的属性,似乎有几种访问属性的方法: document.getElementsByTagName("link")[0]['media'] document.getElementsByTagName("link")[0].media document.getElementsByTagName("link")[0].getAttribute('media') document.getElementsByTagName("link")[0].attributes['media']

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

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

同一个数据有多少条路径,这近乎荒谬。这些方法中有一种远远优于其他方法吗?

前两种方法是相同的。你可以用任何一种。我个人更喜欢
.media
版本,因为我觉得它更容易阅读


最后两个选项取决于
getAttribute()
setAttribute()
,这两个选项在IE中并不总是可靠的。因此,在所有四种选择中,我更喜欢
.media
版本,因为它是最可靠和最可读的。

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

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

在功能上,它们是相等的

就性能而言,前两个在很大程度上是优越的——尽管它们都非常快。看


实际上,前两个更容易阅读,我个人的偏好是第二个。(这也快了一点。)

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

请注意,上一个示例
.attributes['media']
没有像其他方法那样返回字符串。它返回一个属性节点

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

添加更多的技术细节,虽然不同的方法在大多数情况下返回相同的方法,但对于不存在的属性,这不一定是正确的。以下面的HTML为例:
(下面的输出来自Firefox)

请注意,一次返回绝对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
map中创建一个条目

// 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方法修改或属性修改(即预定义属性)时可用的内容。我希望我没有错过任何重要的案例,我的评论已经足够详细,可以看到发生了什么


我希望能对最终名称NodeMap发表评论,因为我想知道Firefox的行为是否正确,从而放弃解析属性的顺序。

请注意:前两个在JavaScript中编译为相同的内容(
.x=[“x”]
),这并不特定于元素属性。它是
getElementsByTagName
,而不是
getElementByTag
。可能是…的重复项,但JSLint会在不需要时抱怨使用方括号表示法。前两个只是语法差异,而不是API差异,它们为您提供了属性,它不一定与属性的值相同。
// 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);