我正在玩获取link
标记的属性,似乎有几种方法可以访问这些属性:
document.getElementsByTagName("link")[0]['media']
document.getElementsByTagName("link")[0].media
document.getElementsByTagName("link")[0].getAttribute('media')
document.getElementsByTagName("link")[0].attributes['media']
接近荒谬的是有多少路径存在于同一数据中。这些方法中的一种远远优于其他方法吗?
答案 0 :(得分:12)
我会在这种情况下使用.media
,因为media
确实是link元素的属性。每个都有它的用途:
['media']
:使用方括号表示法检索“media”属性值。如果您在设计时不知道酒店的名称,请使用方括号表示法。例如,迭代属性时。.media
:检索“media”属性值。我在大多数情况下会使用它。它提供简洁,直接的财产价值。.getAttribute('media')
:检索“media”属性值。如果希望属性的值不一定是元素的属性,请使用此选项。并非所有属性都是属性,并非所有属性都是属性。.attributes['media']
:检索“媒体”属性节点。当您需要有关属性的更多信息而不仅仅是它的值时,请使用属性集合。例如,属性名称。您也可以轻松地使用它来获取值,因为.toString()
返回值,但如果您想要的只是值,那么这可能是过度的。 attributes
集合对iterating the attributes of an element也很有用。答案 1 :(得分:4)
您要查找的方法称为getElementsByTagName
。它返回一个类似数组的元素列表(不是数组)。
请注意,您的上一个示例.attributes['media']
不会像其他方法一样返回字符串。它改为返回一个属性节点。
理论上,访问内容的方式应该是等效的,但浏览器错误会导致其他行为。最好使用抽象层(如jQuery这样的库)来获得一致的行为。如果您打算在没有库的情况下进行编程,那么选择取决于您的品味,但我会说通过属性节点进行的操作通常是最安全的。
要添加更多技术细节,尽管不同的方式在大多数情况下以相同的方式返回,但对于不存在的属性,这不一定是正确的。以下面的HTML为例:<a href='test'>
。您可以在a 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
请注意,有一次返回绝对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的当前状态。它不知道我们通过a
收到的对象getElementsByTagName
的扩展名。
重要的是要注意,操纵JavaScript对象不一定会影响DOM。 DOM仅反映解析时可用的内容以及使用DOM方法或属性修改(具有预定义属性)的修改。我希望我没有错过任何重要案例,而且评论已经足够详细,看看会发生什么。
我很感激对最终的NamedNodeMap的评论,因为我想知道Firefox的行为是否正确,从而放弃解析属性的顺序。
答案 2 :(得分:1)
从功能上讲,它们是平等的。
在性能方面,前两个优势是一个重要因素 - 尽管它们都非常快。请参阅this JSPerf test。
实际上,前两个更容易阅读,而我个人的偏好是第二个。 (这也是头发更快。)
答案 3 :(得分:0)
前两个选项是相同的。你可以使用其中之一。我个人更喜欢.media
版本,因为我觉得它更容易阅读。
最后两个选项取决于getAttribute()
和setAttribute()
,它们在IE中并不总是可靠的。您可以在reference that Matt posted中阅读更多相关内容。因此,我更喜欢所有四种选择中的.media
版本,因为它们最可靠,最易读。