我对一些DOM元素property
与其对应的attributes
之间的关系如何起作用的原因感到困惑。
以下是图书jquery in action 2015 Bear Bibeault
中的图表,显示了DOM元素的property
和attribute
之间的关系。
为了进一步解释这个概念,作者对代码有以下代码和解释。
我的问题是,为什么某些property
和attribute
已同步,为什么有些未同步,为什么有些attributes
没有相应的property
?
我找到great post来解释property
和attribute
之间的关系,但它没有说明为什么会这样设计。我希望了解设计背后的原因。
一个相关的问题,如果我想获取或设置DOM元素的值,我应该获取/设置property
还是attribute
?
我们如何在需要时找到特定property
与其对应的attribute
之间的关系?是否有专门详细说明这种关系的文件?
答案 0 :(得分:13)
DOM在很大程度上“自然地”增长。你必须考虑,HTML(意思是:属性)是第一位的,最初没有任何脚本。最终,Netscape推出了JavaScript,你今天认为它是一个非常有限的API。这个API适用于操作表单,而不是真正的任意HTML元素。然后Netscape和Internet Explorer推出了他们称之为DHTML的不同变体(动态HTML)。 Netscape的变体依赖于一个特殊的<layer>
标签,今天没有人记得它。 Internet Explorer变体允许对HTML元素进行更通用的访问,特别是将属性1:1映射到属性。
虽然Internet Explorer赢得了这场战争,但它的DHTML变体是在人们将HTML属性名称视为固定集合时设计的。对于任意属性,它有太多问题。例如:
class
属性最初无法映射到JavaScript,因为class
是保留关键字。虽然对JavaScript标准的后续更改允许使用保留关键字作为属性名称,但Internet Explorer必须将class
属性映射到className
属性。在JavaScript对象上的元素或className
属性上设置el["class"]
属性会导致热闹的不一致。<FOO SOMEATTIRIBUTE>
并且您尝试从JavaScript访问el.someAttribute
或el.SOMEATTRIBUTE
时发生了什么?我不再记得,但它不漂亮。toString
不可能映射到属性,因为它会掩盖toString()
方法。除了Internet Explorer之外,没有任何浏览器实现过属性到属性的这种1:1映射,甚至Internet Explorer在向后兼容性方面尽快放弃(这需要很长时间)。相反,属性和属性现在被视为单独的命名空间。浏览器将为您提供一些属性作为属性访问和操作的快捷方式,但它们实际上只是为了您的方便。并且存在一些混淆了水域的向后兼容性案例:value
属性和value
属性实际上并未映射到彼此,前者反映了元素的当前状态,而后者反映了其初始状态。
修改:仅供参考,您引用以下声明:
如果属性作为内置属性存在但是它是布尔值,则该值不会同步。
这是错误的,这种行为与布尔与字符串无关。如上所述,value
属性同样缺少checked
属性的同步。另一方面,布尔hidden
属性将与相应的属性正确同步。据我所知,你会发现Netscape引入的原始表单处理API的属性和属性之间缺少同步 - 这只是向后兼容。
所以也许你不应该相信那些用DOM问题在jQuery上写书的人。毕竟,这些明确地选择退出直接触摸DOM,并选择完全不同的表示与其自己的一组怪癖。
答案 1 :(得分:3)
您将在HTML规范中找到答案。我首先要求您查看input
element(标题为“内容属性”和“DOM界面”)的属性和属性以及有关attribute reflection(第一段)的部分。
您会注意到所有属性都有相应的属性,操作属性会更改它反映的属性。值得注意的是:
(1)属性可以由名称略有不同的属性反映。经典示例是class
属性,它由className
属性和for
属性反映,由htmlFor
属性反映。
(2)同样checked
attribute由defaultChecked
property反映,而checked
property代表复选框的内部状态,与checked
属性无关。这总是引起程序员(和书籍作者)的混淆。这个答案的结尾解释了差异。
(3)虚构属性(例如示例中的“book”属性)不会生成相应的属性,反之亦然。为此,HTML规范描述了一种名为data attributes和dataset
property的机制。
一个相关的问题,如果我想获取或设置DOM元素的值, 我应该获取/设置
property
还是attribute
?
取决于。例如,以下两个产生相同的结果和HTML:
document.getElementById("div-1").title = "Hello";
document.getElementById("div-1").setAttribute("title") = "Hello";
但是,对于表单元素,您应该操纵状态而不是属性。假设您有这个HTML标记:
<input type="checkbox" id="checkbox-1">
然后执行以下任一操作:
document.getElementById("checkbox-1").defaultChecked = true;
document.getElementById("checkbox-1").setAttribute("checked", "checked");
结果如下:
<input type="checkbox" id="checkbox-1" checked="checked">
但是实际上是否检查了复选框取决于控件的肮脏(即,如果其状态在某个时刻发生了变化)。对于表单元素,您通常会操作与内部状态对应的属性:
document.getElementById("checkbox-1").checked = true;