2016-09-04 260 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">