getAttribute()和Element对象属性之间的区别是什么?

99

Element.getAttribute("id")Element.id 这样的表达式返回相同的结果。

当我们需要 HTMLElement 对象的属性时,应该使用哪一个?

这些方法(如 getAttribute()setAttribute())是否存在跨浏览器问题?

或者直接访问对象属性与使用这些属性方法之间是否有性能影响?


1
类似问题:HTML中的属性和特性 - sleske
7个回答

138
getAttribute 方法可以获取 DOM 元素的属性,而 el.id 则可以获取该 DOM 元素的属性值。它们并不相同。
大部分情况下,DOM 属性会和属性值同步。
然而,这种同步并不能保证两者的值完全一致。一个经典的例子就是针对锚点元素的 el.hrefel.getAttribute('href')
例如:
<a href="/" id="hey"></a>
<script>
var a = document.getElementById('hey')
a.getAttribute('href') // "/"
a.href // Full URL except for IE that keeps '/'
</script>

这种行为发生的原因是根据W3C规定,href属性必须是一个格式正确的链接。大多数浏览器都遵守这个标准(你猜谁不遵守?)。
还有一个情况是input元素的checked属性。DOM属性返回true或false,而属性返回字符串"checked"或空字符串。
然后,还有一些属性是单向同步的。最好的例子是input元素的value属性。通过DOM属性更改其值不会更改属性的值(编辑:查看第一个评论以获取更精确的信息)。
因此,建议您继续使用DOM属性而不是属性,因为它们在不同浏览器之间的行为不同。
实际上,只有两种情况需要使用属性:
  1. 自定义HTML属性,因为它没有与DOM属性同步。
  2. 访问内置的HTML属性,该属性未从属性同步,并且您确定需要该属性(例如,input元素的原始value)。

如果您想要更详细的解释,我强烈建议您阅读此页面。这只需要几分钟时间,但您将对信息感到高兴(我在这里总结了信息)。


10
总体而言,建议不错。但同步方面有些偏差:输入框的“value”属性确实从属性中获取其初始值,但在其他方面并未与属性绑定。相反,“value”属性与“defaultValue”属性完全同步。同样,“checked”属性和“defaultChecked”属性也是如此。除了旧版IE(<=7和后续兼容模式),该浏览器的“getAttribute()”和“setAttribute()”功能已经失效。 - Tim Down
将您的评论添加为“进一步解释” :-) - Florian Margaine
2
我认为你的第一个例子是错误的。a.href 返回完整的 URL,而 a.getAttribute("href") 返回 HTML 源代码中定义的属性。 - Salman A
如果您想确定一个值是否为非默认值,最好使用属性。许多现代浏览器将返回默认值(例如“input.formAction”)或空字符串(例如“a.download”),这会使事情变得模糊不清。唯一的例外是那些不是双向同步的值,比如“value”。 - Kevin Li
如果在DOM中根本没有设置id,则getAttribute将返回null,而element.id将返回空字符串。这是一个标准吗? - Maciej Krawczyk
另一个你可能想使用getAttribute的情况是在<form>元素中。如果你有一个带有id="id"或name="id"的子元素的<form>,那么formelem.id就是子元素,而不是表单元素的id。 - Debby Mendez

14

getAttribute('attribute') 通常会返回属性值的字符串,在页面的HTML源代码中定义的内容一致。

然而,element.attribute 可能返回属性的规范化或计算值。例如:

  • <a href="/foo"></a>
    • a.href 将包含完整的 URL
  • <input type="checkbox" checked>
    • input.checked 将是 true (布尔类型)
  • <input type="checkbox" checked="bleh">
    • input.checked 将是 true (布尔类型)
  • <img src='http://dummyimage.com/64x64/000/fff'>
    • 在图像加载之前, img.width 将是 0(数字类型)
    • 在图像(或它的前几个字节)加载时, img.width 将是 64(数字类型)
  • <img src='http://dummyimage.com/64x64/000/fff' width="50%">
    • img.width 将是 计算后的 50%
  • <img src='http://dummyimage.com/32x32/000/fff' style='width: 50px'>
    • img.width 将是 50(数字类型)
  • <div style='background: lime;'></div>
    • div.style 将是一个对象

3

.id 可以节省函数调用开销(虽然很小,但您提出了这个问题。)


嗨gdoron,只是出于好奇:我试图找到一个“官方”的解释(超越经验测试,这已经足够清楚了;)),但没有成功。你有相关链接吗? - mamoo

3
根据this jsPerf testgetAttributeid属性更慢。 附注 奇怪的是,在IE8上,这两个语句表现都非常差(与其他浏览器相比)。

3

除非您有特定原因不使用属性,否则请始终使用属性。

  • getAttribute()setAttribute()在旧版IE(以及后期版本的兼容性模式)中存在问题
  • 属性更加方便(特别是那些对应于布尔属性的属性)

以下是一些例外情况

  • 访问<form>元素的属性
  • 访问自定义属性(尽管我不鼓励使用自定义属性)

我在SO上几次写过这个主题:


在IE 8之前,属性和特性被视为相同的(http://msdn.microsoft.com/en-us/library/dd347148(v=VS.85).aspx)。正如您之前提到的,属性是更好的选择。 - user1385191
@MattMcDonald:是的,那就是我所提到的破碎性。我在这个答案中没有详细展开它,因为我觉得我在其他我链接到的答案中已经做得足够了 :) - Tim Down

0
尝试下面的示例以完全理解此内容。对于以下DIV: <div class="myclass"></div> Element.getAttribute('class')将返回myclass,但您必须使用Element.className从DOM属性中检索它。

0

这种情况对基于属性的CSS样式设置有很大影响。

请考虑以下内容:

const divs = document.querySelectorAll('div');

divs[1].custom = true;
divs[2].setAttribute('custom', true);
div {
  border: 1px solid;
  margin-bottom: 8px;
}

div[custom] {
  background: #36a;
  color: #fff;
}
<div>A normal div</div>
<div>A div with a custom property set directly.</div>
<div>A div with a custom attribute set with `setAttribute`</div>

直接设置自定义属性的 div 不会反映到属性值,并且在 CSS 中无法通过属性选择器 (div[custom]) 进行选择。

然而,使用 setAttribute 设置自定义属性的 div 可以被 CSS 属性选择器选择并进行相应的样式设置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接