2016-09-04 330 views
2

我很困惑“HTML属性”和“DOM元素的属性”之间的差异。从this post,我了解到getAttribute("class")返回前者,而element.className返回后者。不过,我便无法理解下列代码的输出:“HTML属性”与“DOM元素的属性”

var span = document.querySelector("#span"); 
 
console.log(span.className + ' ' + span.getAttribute("class")); 
 
span.className = "bar"; 
 
console.log(span.className + ' ' + span.getAttribute("class"));
<span id="span" class="foo"><span>

我希望得到的结果是

foo foo 
bar foo 

,因为在我的理解我的HTML文件的内容在运行javascript时没有改变。此外,当我用span.setAttribute('class', 'bar');替换span.className = "bar";行时,仍然会有相同的结果。

我的问题是:“HTML属性”和“DOM元素的属性”之间的区别和关系是什么?

+3

HTML属性是你在标记写什么。这些属性就像其他所有东西一样成为DOM的一部分。其中一些属性在创建时直接映射到DOM元素上。其中,它们的一个子集维护着属性和属性之间的实时映射,所以两者在更改时都会更新。 'class'属性就是其中之一。 –

+1

@squint我认为这可以是一个很好的答案。 –

+0

我会让你或其他人深入了解一切的复杂性并发布答案。我这的工作都干完了... –

回答

3

为了进一步混淆事项,HTML5规范分别将它们称为内容属性和IDL属性。

它们有时是由相同的名称相关联,有时不相关。

在最常见的关联类型中,这两种类型的属性被认为是相互“反射”的,所以当一个属性发生变化时,另一个属性也会发生变化。 HTML5在Reflecting content attributes in IDL attributes中对此进行了描述。第一段说:

某些IDL属性被定义为反映特定内容 属性。这意味着在获取时,IDL属性返回 内容属性的当前值,并且在设置时,IDL 属性将内容属性的值更改为给定的 值。

有时IDL属性和反映彼此的内容属性具有不同的名称。例如,输入“value”内容属性由IDL属性defaultValue反映。

有时两者之间的关联更复杂;更改为一个可能会影响另一个,但不是一个直接的一对一映射。

2

在大多数情况下,对属性的修改也将在属性中表示,反之亦然。就像你的示例代码一样。

但是,表单元素中的某些属性/属性是不同的。最初,属性值是从相关属性中检索出来的,但它们不会再相互影响。

请在每次修改后注意标记:

var el = document.querySelector('input') 
 
console.log(el.value + ' ' + el.getAttribute('value')) 
 
console.log(el.outerHTML) 
 
el.value = 'prop' 
 
console.log(el.value + ' ' + el.getAttribute('value')) 
 
console.log(el.outerHTML) 
 
el.setAttribute('value', 'attr') 
 
console.log(el.value + ' ' + el.getAttribute('value')) 
 
console.log(el.outerHTML)
<input type="text" value="123">