淺談js裡的attributes和與之相關的一些屬性
在前端裡,想要對靜態的HTML變得更加的動態,就必須要對HTML的dom進行操作,dom猶如一個樹,樹的最底層是文件節點,這個節點順著上來就到了html節點,也就是根節點。這個根節點有兩個分支,一個是body,另一個是head。head裡面有很多個子節點,必須要有的是title節點,其他常見的有meta、style、link等,而body裡面也有無數個節點。就拿body裡面的p節點來講,裡面就有文字,這個文字也是一個節點,稱為#text節點。這些就是整個dom樹的大概。
在瞭解了這些節點後,當我們想要獲取一個節點的名字或者改變節點裡的屬性值或文字值的時候怎麼辦?這裡就要提nodeName、nodeValue和nodeType了。nodeName是隻讀屬性,不能寫入和修改,它能夠獲取元素節點的標籤名、屬性節點的屬性名、文字節點的#text和文件節點的#document。而nodeValue能夠寫入,它能夠獲取文字節點的內容、屬性節點的屬性值,在元素節點裡它獲取的結果是undefined或者null,nodeValue可以被textContent屬性替換。而nodeType返回的是節點型別,不能修改的,常見的節點型別有:
詳細程式碼如下:
<body>
<p id='ha'>a</p>
</body>
<script type="text/javascript">
var a = document.getElementById('ha')
console.log(a.nodeName)
console.log(a.firstChild.nodeValue = 'ha')
console.log(a.nodeType)
</script>
那麼我們想對節點進行操作怎麼辦,這裡有幾個屬性:getAttributeNode、setAttributeNode和removeAttributeNode。這三個方法分別表示為:getAttributeNode:獲取一個節點作為物件、setAttributeNode:設定一個節點和removeAttributeNode:刪除一個節點。這三個屬性在DOM4版本中已經不推薦使用了,在DOM4版本中推薦使用的是getAttribute、setAttribute和removeAttribute。在DOM4裡,屬性已不在作為一個特殊的節點了。下面的例子是展示的是新的標準的寫法:
首先是getAttribute,它與getAttributeNode不同的是,返回的是屬性值而不是一個物件:
<body>
<div id = "t"><input type = "hidden" id = "sss" value = "aaa"></div>
</body>
<script>
var a = document.getElementById("sss").getAttribute("value");
console.log(a)
</script>
而getAttributeNode想要得到與上面相同的結果,需要這樣寫:var a = document.getElementById("sss").getAttributeNode("value"); console.log(a.value)
然後是setAttribute,它是設定屬性和屬性值,而setAttributeNode是設定一個節點,setAttributeNode不如setAttribute靈活:
<body>
<div id = "t"><input type = "hidden" id = "sss" value = "aaa"></div>
</body>
<script>
var a = document.getElementById("t")
a.firstChild.setAttribute('ha','haha');
console.log(a.innerHTML)
</script>
而setAttributeNode想要實現上面的例子,首先先要創造一個屬性名,然後給屬性賦值,最後新增到節點上:var a = document.createAttribute('ha')
a.nodeValue = 'haha'
var b = document.getElementById('t')
b.firstChild.setAttributeNode(a)
console.log(b.innerHTML)
最後是removeAttribute,與removeAttributeNode相同的是都是刪除一個屬性,但是區別是,前者沒有返回值,而後者以attr物件形式返回被刪除的屬性:
<body>
<div id = "t"><input type = "hidden" id = "sss" value = "aaa"></div>
</body>
<script>
var a = document.getElementById("t")
a.firstChild.setAttribute('ha','haha');
a.firstChild.removeAttribute('ha')
console.log(a.innerHTML)
</script>
由於removeAttributeNode的引數是物件,所以用getAttributeNode來獲得這個節點物件,所以本身這個方法用的比較費勁:var a = document.getElementById("t")
a.firstChild.setAttribute('ha','haha');
var b = a.firstChild.getAttributeNode('ha')
a.firstChild.removeAttributeNode(b)
console.log(a.innerHTML)
基礎鋪好了好,就介紹標題裡面所提的attributes了。這個attributes返回的是某個節點裡所有屬性的集合,返回的是一個NamedNodeMap物件,在這個物件裡分兩部分,兩部分的值都相同只是鍵不同,一部分的鍵名以0開始依次增加排列,另一部分的鍵名則是以屬性名來命名的,如上面的這個HTML程式碼,把下面的這段程式碼放到控制檯那裡輸出就會看到這兩部分:
document.getElementById('sss').attributes
不過好可惜,attributes屬性在DOM4裡面被列為不推薦使用,所以這裡也沒必要深究這個attributes了。這裡只列一下attributes的一些常見用法,如下面的兩個得到的都是同一個結果:
<body>
<p id="intro">Hello World!</p>
</body>
<script type="text/javascript">
x=document.getElementById("intro");
console.log(x.attributes['id'].nodeName);
console.log(x.attributes.getNamedItem("id").nodeName);
</script>
最後樓主翻閱MDN的時候,發現nodeName、nodeValue和nodeType都不推薦使用,nodeName被name替換,nodeValue被value替換。不得不感慨DOM4簡直想要來個大變臉。