JS操作屬性節點(非常詳細)

2020-07-16 10:05:12
屬性節點的主要特徵值:nodeType 等於 2、nodeName 等於屬性的名稱、nodeValue 等於屬性的值、parentNode 等於 null,在 HTML 中不包含子節點。屬性節點繼承於 Node 型別,包含以下 3 個專用屬性。
  • name:表示屬性名稱,等效於 nodeName。
  • value:表示屬性值,可讀可寫,等效於 nodeValue。
  • specified:如果屬性值是在程式碼中設定的,則返回 true;如果為預設值,則返回 false。

建立屬性節點

使用 document 物件的 createAttribute() 方法可以建立屬性節點,具體用法如下:

document.createAttribute(name)

引數 name 表示新建立的屬性的名稱。

範例1

下面範例建立一個屬性節點,名稱為 align,值為 center,然後為標籤 <div id="box"> 設定屬性 align,最後分別使用 3 種方法讀取屬性 align 的值。
<div id="box">document.createAttribute(name)</div>
<script>
    var element = document.getElementById("box");
    var attr = document.createAttribute("align");
    attr.value = "center";
    element.setAttributeNode(attr);
    console.log(element.attributes["align"].value);  //"center"
    console.log(element.getAttributeNode("align").value);  //"center"
    console.log(element.getAttribute("align"));  //"center"
</script>

屬性節點一般位於元素的頭部標籤中。元素的屬性列表會隨著元素資訊預先載入,並被儲存在關聯陣列中。例如,針對下面 HTML 結構。
<div id="div1" class="style1" lang="en" title="div"></div>
當 DOM 載入後,表示 HTML div 元素的變數 divElement 就會自動生成一個關聯集合,它以名值對形式檢索這些屬性。
divElement.attributes = {
    id : "div1",
    class : "style1",
    lang : "en",
    title : "div"
}
在傳統 DOM 中,常用點語法通過元素直接存取 HTML 屬性,如 img.src、a.href 等,這種方式雖然不標準,但是獲得了所有瀏覽器的支援。

範例2

img 元素擁有 src 屬性,所有影象物件都擁有一個 src 指令碼屬性,它與 HTML 的 src 特性關聯在一起。下面兩種用法都可以很好地工作在不同瀏覽器中。
<img id="img1" src="" />
<script>
    var img = document.getElementById("img1");
    img.setAttribute("src", "http://www.w3.org");  //HTML 屬性
    img.src = "http://www.w3.org";  //JavaScript 屬性
</script>
類似的還有 onclick、style 和 href 等。為了保證 JavaScript 指令碼在不同瀏覽器中都能很好地工作,建議採用標準用法,而且很多 HTML 屬性並沒有被 JavaScript 對映,所以也就無法直接通過指令碼屬性進行讀寫。

讀取屬性值

使用元素的 getAttribute() 方法可以讀取指定屬性的值。用法如下:

getAttribute(name)

引數 name 表示屬性名稱。

使用元素的 attributes 屬性、getAttributeNode() 方法可以返回對應屬性節點。

範例1

下面範例存取紅色盒子和藍色盒子,然後讀取這些元素所包含的 id 屬性值。
<div id="red">紅盒子</div>
<div id="blue">藍盒子</div>
<script>
    var red = document.getElementById("red");  //獲取紅色盒子
    console.log(red.getAttribute("id"));  //顯示紅色盒子的id屬性值
    var blue = document.getElementById("blue");  //獲取藍色盒子
    console.log(blue.getAttribute("id"));  //顯示藍色盒子的id屬性值
</script>

範例2

HTML DOM 也支援使用點語法讀取屬性值,使用比較簡便,也獲得了所有瀏覽器的支援。
var red = document.getElementById("red");
console.log(red.id);
var blue = document.getElementById("blue");
console.log(blue.id);

對於 class 屬性,則必須使用 className 屬性名,因為 class 是 JavaScript 的保留字;對於 for 屬性,則必須使用 htmlFor 屬性名,這與 CSS 指令碼中 float 和 text 屬性被改名為 cssFloat 和 cssText 是一個道理。

範例3

使用 className 讀寫樣式類。
<label id="label1" class="class1" for="textfield">文字方塊:
    <input type="text" name="textfield" id="textfield" />
</label>
<script>
    var label = document.getElementById("label1");
    console.log(label.className);
    console.log(label.htmlFor);
</script>

範例4

對於複合類樣式,需要使用 split() 方法劈開返回的字串,然後遍歷讀取類樣式。
<div id="red" class="red blue">紅盒子</div>
<script>
    //所有類名生成的陣列
    var classNameArray = document.getElementById("red").className.split(" ");
    for (var i in classNameArray) {  //遍歷陣列
        console.log(classNameArray[i]);  //當前class名
    }
</script>

設定屬性值

使用元素的 setAttribute() 方法可以設定元素的屬性值。用法如下:

setAttribute(name, value)

引數 name 和 value 分別表示屬性名稱和屬性值。屬性名和屬性值必須以字串的形式進行傳遞。如果元素中存在指定的屬性,它的值將被重新整理;如果不存在,則 setAttribute() 方法將為元素建立該屬性並賦值。

範例1

下面範例分別為頁面中 div 元素設定 title 屬性。
<div id="red">紅盒子</div>
<div id="blue">藍盒子</div>
<script>
    var red = document.getElementById("red");  //獲取紅盒子的參照
    var blue= document.getElementById("blue");  //獲取藍盒子的參照
    red.setAttribute("title", "這是紅盒子");  //為紅盒子物件設定title屬性和值
    blue.setAttribute("title", "這是藍盒子");  //為藍盒子物件設定title屬性和值
</script>

範例2

下面範例定義了一個文字節點和元素節點,並為一級標題元素設定 title 屬性,最後把它們新增到文件結構中。
var hello = document.createTextNode("Hello World!");  //建立一個文字節點
var h1 = document.createElement("h1");  //建立一個一級標題
h1.setAttribute("title", "你好,歡迎光臨!");  //為以及標題定義title 屬性
h1.appendChild(hello);  //把文字節點增加到一級標題中
document.body.appendChild(h1);  //把一級標題增加到文件

範例3

也可以使用快捷方法設定 HTML DOM 文件中元素的屬性值。
<label id="label1">文字方塊:
    <input type="text" name="textfield" id="textfield" />
</label>
<script>
    var label1 = document.getElementById("label1");
    label.className = "class1";
    label.htmlFor = "textfield";
</script>
DOM 支援使用 getAttribute() 和 setAttribute() 方法讀寫自定義屬性,不過 IE 6.0 及其以下版本瀏覽器對其的支援不是很完善。

範例4

直接使用 className 新增類樣式,會覆蓋掉元素原來的類樣式。這時可以採用疊加的方式新增類。
<div id="red">紅盒子</div>
<script>
    var red = document.getElementById("red");
    red.className = "red";
    red.className += "blue";
</script>

範例5

使用疊加的方式新增類也存在問題,這樣容易新增大量重複的類。為此,定義一個檢測函數,判斷元素是否包含指定的類,然後再決定是否新增類。
<script>
    function hasClass (element, className) {  //檢測類名函數
        var reg = new RegExp('(s|^)' + className + '(s|$)');
        return reg.test(element.className);  //使用正則檢測是否有相同的樣式
    }
    function addClass (element, className) {  //新增類名函數
        if (! hasClass (element, className))
            element.className += ' ' + className;
    }
</script>
<div id="red">紅盒子</div>
<script>
    var red = document.getElementById("red");
    addClass(red, 'red');
    addClass(red, 'blue');
</script>

刪除屬性

使用元素的 removeAttribute() 方法可以刪除指定的屬性。用法如下:

removeAttribute(name)

引數 name 表示元素的屬性名。

範例1

下面範例演示了如何動態設定表格的邊框。
<script>
    window.onload = function () {  //係結頁面載入完畢時的事件處理常式
        var table = document.getElementByTagName("table")[0];  //獲取表格外框的參照
        var del = document.getElementById("del");
        var reset = document.getElementById("reset");
        del.onclick = function () {
            table.removeAttribute("border");
        }
        reset.onclick = function () {
            table.setAttribute("border", "2");
        }
</script>
<table width="100%" border="2">
    <tr>
        <td>資料表格</td>
    <tr>
</table>
<button id="del">刪除</button><button id="reset">恢復</button>
在上面範例中設計了兩個按鈕,並分別系結了不同的事件處理常式。單擊“刪除”按鈕即可呼叫表格的 removeAttribute() 方法清除表格邊框,單擊“恢復”按鈕即可呼叫表格的 setAttribute() 方法重新設定表哥便可的粗細。

範例2

下面範例演示了如何自定義刪除類函數,並呼叫該函數刪除指定類名。
<script>
    function hasClass (element, className) {  //類名檢測函數
        var reg = new RegExp ('(s|^)' + className + '(s|$)');
        return reg.test (element, className);  //使用正則檢測是否有相同的樣式
    }
    function deleteClass (element, className) {
        if (hasClass (element, className)) {
            element.className.replace (reg, ' ');  //捕獲要刪除樣式,然後替換為空白字串
        }
    }
</script>
<div id="red" class="red blue bold">盒子</div>
<script>
    var red = document.getElementById ("red");
    deleteClass (red, 'blue');
</script>
上面程式碼使用正規表示式檢測 className 屬性值字串中是否包含指定的類名,如果存在,則使用空字串替換掉匹配到的子字串,從而實現刪除類名的目的。

使用類選擇器

HTML 5 為 document 物件和 HTML 元素新增了 getElementsByClassName() 方法,使用該方法可以選擇指定類名的元素。getElementsByClassName() 方法可以接收一個字串引數,包含一個或多個類名,類名通過空格分隔,不分先後順序,方法返回帶有指定類的所有元素 NodeList。

瀏覽器支援狀態:IE 9+、Firefox 3.0+、Safari 3+、Chrome 和 Opera 9.5+。

如果不考慮相容早期 IE 瀏覽器或者怪異模式,使用者可以放心使用。

範例1

下面範例使用 getElementsByClassName("red") 方法選擇文件中所有包含 red 類的元素。
<div class="red">紅盒子</div>
<div class="blue red">藍盒子</div>
<div class="green red">綠盒子</div>
<script>
    var divs = document.getElementsByClassName("red");
    for (var i = 0; i < divs.length; i ++) {
        console.log(divs[i].innerHTML);
    }
</script>

範例2

下面範例使用 document.getElementById("box") 方法先獲取 <div id="box">,然後在它下面使用 getElementsByClassName("blue red") 選擇同時包含 red 和 blue 類的元素。
<div id="box">
    <div class="blue red green">blue red green</div>
</div>
<div class="blue red black">blue red black</div>
<script>
    var divs = document.getElementById("box").getElementsByClassName("blue red");
    for (var i = 0; i < divs.length; i ++) {
        console.log(divs[i].innerHTML);
    }
</script>
在 document 物件上呼叫 getElementsByClassName() 會返回與類名匹配的所有元素,在元素上呼叫該方法就只會返回後代元素中匹配的元素。

自定義屬性

HTML 5 允許使用者為元素自定義屬性,但要求新增 data- 字首,目的是為元素提供與渲染無關的附加資訊,或者提供語意資訊。例如:
<div id="box" data-myid="12345" data-myname="zhangsan" data-mypass="zhang123">自定義資料屬性</div>
新增自定義屬性之後,可以通過元素的 dataset 屬性存取自定義屬性。dataset 屬性的值是一個 DOMStringMap 範例,也就是一個名值對的對映。在這個對映中,每個 data-name 形式的屬性都會有一個對應的屬性,只不過屬性名沒有 data- 字首。

瀏覽器支援狀態:Firefox 6+ 和 Chrome。

範例

下面程式碼演示了如何自定義屬性,以及如何讀取這些附加資訊。
var div = document.getElementById("box");
//存取自定義屬性值
var id = div.dataset.myid;
var name = div.dataset.myname;
var pass = div.dataset.mypass;
//重置自定義屬性值
div.dataset.myid = "66666";
div.dataset.myname = "zhangsan";
div.dataset.mypass = "zhangsan666";
//檢測自定義屬性
if (div.dataset.myname) {
    console.log(div.dataset.myname);
}
雖然上述用法未獲得所有瀏覽器支援,但是我們仍然可以使用這種方式為元素新增自定義屬性,然後使用 getAttribute() 方法讀取元素附加的資訊。