JavaScript DOM,如何处理“特殊属性”与属性相对比的情况?

12

问题是使用属性还是属性值。

没有找到相关文档,因此做了一些测试(使用chromium 12):

属性 <=> 属性值

accept, alt, formMethod, formTarget, id, name, placeholder, type, maxlength, size
form: method, name, target, action, enctype
  • 可以设置属性或属性值
  • 会反映到属性或属性值
  • 例外1:如果表单属性名称存在,则首先查找该元素!
  • 例外2:action属性将使用值重写自身,并将设置的值传递给属性值
  • 例外3:enctype保持其完整性,但将设置的值传递给属性值

属性 <= 属性值

value, autofocus, checked, disabled, formNoValidate, multiple, required
  • 设置属性对属性值没有影响
  • 设置属性值也会设置属性

属性 => 属性值

indeterminate
  • 设置属性也会设置属性值
  • 设置属性值对属性没有影响

属性 >< 属性值

defaultValue, validity, defaultChecked, readOnly
form: novalidate
  • 设置属性或属性值对另一个没有影响


对我来说,这似乎是随机的行为。

给定要应用于元素的随机属性/值,这里是我想出的最佳规则(根据Tim Down(感谢!)的修改):

  • 如果是类,请使用 classList 写入,使用 className 属性读取

  • 如果是表单,请始终使用属性值读取(并要小心一些)

  • 如果typeof element[propName] != "undefined",那么使用属性,即element[attr]=val

  • 否则,使用属性设置方法,即element.setAttribute(attr,val)

  • 这样翻译是否准确?

    注意:有趣的是,如果您有一个名为"novalidate"的元素表单,是否可以访问表单自身的novalidate属性?

    1个回答

    12
    除了下面列出的少数特殊情况,始终使用属性。一旦浏览器解析了初始HTML,除非你将DOM序列化回HTML,否则属性对你没有任何帮助。
    始终优先考虑属性的原因:
    - 处理属性更简单(参见布尔属性,如checked: 只需使用truefalse,无需担心是否应该删除属性,或将其设置为"""checked") - 并非每个属性都映射到同名的属性。例如,复选框或单选按钮的checked属性不对应于任何属性;checked属性对应于defaultChecked属性,并且当用户与元素交互时不会更改(除了在旧版IE中;请参见下一点)。同样适用于valuedefaultValue。 - setAttribute()getAttribute()在旧版IE中存在问题
    特殊情况:
    • <form>元素的属性。由于每个表单输入都映射到其父<form>元素的属性,相应地为其name,因此更安全的做法是使用setAttribute()getAttribute()来获取表单的属性,例如actionnamemethod
    • 自定义属性,例如<p myspecialinfo="cabbage">。这些通常不会在DOM元素对象上创建等效的属性,因此应使用setAttribute()getAttribute()

    最后需要考虑的一点是,属性和属性名之间没有精确的对应关系。例如,class属性的属性等价物是className,而for属性的属性是htmlFor


    我认为我们的意思是一样的,除了两件事:1)name,如果存在一个名称为“name”的元素,则在表单中将是错误的,2)给定随机的属性/值对,如果该属性不是属性,则将被视为属性。因为该应用程序仅针对高端浏览器进行规范化,所以无需支持旧版本的IE(截至目前为止,据我所知,甚至包括更新版本)。 - cc young
    name 是一个公平的观点,也是表单元素的特例。很遗憾,正是因为这个原因(仅提供 form.elements 不好吗?),表单输入被映射到 <form> 元素的属性中。至于第二点,你是指自定义属性(例如 <p myspecialattr="cheese">)吗?如果是这样,我会同意,因为 getAttribute()setAttribute() 是访问它们的唯一方式。顺便说一下,不能保证 hasOwnProperty() 在 DOM 节点等宿主对象上有效,所以我会使用不同的测试方法。 - Tim Down
    哇-你真棒!首先,我将测试表单属性,看看它们与属性的同步程度如何。其次,如果不使用hasOwnProperty(),你会用什么? - cc young
    1
    通常情况下,使用typeof即可。typeof element[propName] != "undefined"就可以工作了。你可能可以在你的目标浏览器中使用hasOwnProperty(),但是typeof更安全,因为宿主对象必须响应typeof,但不一定要继承自Object.prototype,而hasOwnProperty()则是在Object.prototype中定义的。 - Tim Down
    完成了对表单属性的工作-请查看更新的比较。异常2实际上相当不错。总之,有点棘手。 - cc young

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