屬性的操作
HTML 元素包括標簽名和若干個鍵值對,這個鍵值對就稱為“屬性”(attribute)。
<a id="test" rel="external nofollow" target="_blank" >
鏈接
</a>
上面代碼中,a
元素包括兩個屬性:id
屬性和href
屬性。
屬性本身是一個對象(Attr
對象),但是實際上,這個對象極少使用。一般都是通過元素節(jié)點對象(HTMlElement
對象)來操作屬性。本章介紹如何操作這些屬性。
Element.attributes 屬性
元素對象有一個attributes
屬性,返回一個類似數組的動態(tài)對象,成員是該元素標簽的所有屬性節(jié)點對象,屬性的實時變化都會反映在這個節(jié)點對象上。其他類型的節(jié)點對象,雖然也有attributes
屬性,但返回的都是null
,因此可以把這個屬性視為元素對象獨有的。
單個屬性可以通過序號引用,也可以通過屬性名引用。
// HTML 代碼如下
// <body bgcolor="yellow" onload="">
document.body.attributes[0]
document.body.attributes.bgcolor
document.body.attributes['ONLOAD']
注意,上面代碼的三種方法,返回的都是屬性節(jié)點對象,而不是屬性值。
屬性節(jié)點對象有name
和value
屬性,對應該屬性的屬性名和屬性值,等同于nodeName
屬性和nodeValue
屬性。
// HTML代碼為
// <div id="mydiv">
var n = document.getElementById('mydiv');
n.attributes[0].name // "id"
n.attributes[0].nodeName // "id"
n.attributes[0].value // "mydiv"
n.attributes[0].nodeValue // "mydiv"
下面代碼可以遍歷一個元素節(jié)點的所有屬性。
var para = document.getElementsByTagName('p')[0];
var result = document.getElementById('result');
if (para.hasAttributes()) {
var attrs = para.attributes;
var output = '';
for(var i = attrs.length - 1; i >= 0; i--) {
output += attrs[i].name + '->' + attrs[i].value;
}
result.textContent = output;
} else {
result.textContent = 'No attributes to show';
}
元素的標準屬性
HTML 元素的標準屬性(即在標準中定義的屬性),會自動成為元素節(jié)點對象的屬性。
var a = document.getElementById('test');
a.id // "test"
a.href // "http://www.example.com/"
上面代碼中,a
元素標簽的屬性id
和href
,自動成為節(jié)點對象的屬性。
這些屬性都是可寫的。
var img = document.getElementById('myImage');
img.src = 'http://www.example.com/image.jpg';
上面的寫法,會立刻替換掉img
對象的src
屬性,即會顯示另外一張圖片。
這種修改屬性的方法,常常用于添加表單的屬性。
var f = document.forms[0];
f.action = 'submit.php';
f.method = 'POST';
上面代碼為表單添加提交網址和提交方法。
注意,這種用法雖然可以讀寫屬性,但是無法刪除屬性,delete
運算符在這里不會生效。
HTML 元素的屬性名是大小寫不敏感的,但是 JavaScript 對象的屬性名是大小寫敏感的。轉換規(guī)則是,轉為 JavaScript 屬性名時,一律采用小寫。如果屬性名包括多個單詞,則采用駱駝拼寫法,即從第二個單詞開始,每個單詞的首字母采用大寫,比如onClick
。
有些 HTML 屬性名是 JavaScript 的保留字,轉為 JavaScript 屬性時,必須改名。主要是以下兩個。
for
屬性改為htmlFor
class
屬性改為className
另外,HTML 屬性值一般都是字符串,但是 JavaScript 屬性會自動轉換類型。比如,將字符串true
轉為布爾值,將onClick
的值轉為一個函數,將style
屬性的值轉為一個CSSStyleDeclaration
對象。因此,可以對這些屬性賦予各種類型的值。
屬性操作的標準方法
概述
元素節(jié)點提供六個方法,用來操作屬性。
getAttribute()
getAttributeNames()
setAttribute()
hasAttribute()
hasAttributes()
removeAttribute()
這有幾點注意。
(1)適用性
這六個方法對所有屬性(包括用戶自定義的屬性)都適用。
(2)返回值
getAttribute()
只返回字符串,不會返回其他類型的值。
(3)屬性名
這些方法只接受屬性的標準名稱,不用改寫保留字,比如for
和class
都可以直接使用。另外,這些方法對于屬性名是大小寫不敏感的。
var image = document.images[0];
image.setAttribute('class', 'myImage');
上面代碼中,setAttribute
方法直接使用class
作為屬性名,不用寫成className
。
Element.getAttribute()
Element.getAttribute
方法返回當前元素節(jié)點的指定屬性。如果指定屬性不存在,則返回null
。
// HTML 代碼為
// <div id="div1" align="left">
var div = document.getElementById('div1');
div.getAttribute('align') // "left"
Element.getAttributeNames()
Element.getAttributeNames()
返回一個數組,成員是當前元素的所有屬性的名字。如果當前元素沒有任何屬性,則返回一個空數組。使用Element.attributes
屬性,也可以拿到同樣的結果,唯一的區(qū)別是它返回的是類似數組的對象。
var mydiv = document.getElementById('mydiv');
mydiv.getAttributeNames().forEach(function (key) {
var value = mydiv.getAttribute(key);
console.log(key, value);
})
上面代碼用于遍歷某個節(jié)點的所有屬性。
Element.setAttribute()
Element.setAttribute
方法用于為當前元素節(jié)點新增屬性。如果同名屬性已存在,則相當于編輯已存在的屬性。該方法沒有返回值。
// HTML 代碼為
// <button>Hello World</button>
var b = document.querySelector('button');
b.setAttribute('name', 'myButton');
b.setAttribute('disabled', true);
上面代碼中,button
元素的name
屬性被設成myButton
,disabled
屬性被設成true
。
這里有兩個地方需要注意,首先,屬性值總是字符串,其他類型的值會自動轉成字符串,比如布爾值true
就會變成字符串true
;其次,上例的disable
屬性是一個布爾屬性,對于<button>
元素來說,這個屬性不需要屬性值,只要設置了就總是會生效,因此setAttribute
方法里面可以將disabled
屬性設成任意值。
Element.hasAttribute()
Element.hasAttribute
方法返回一個布爾值,表示當前元素節(jié)點是否包含指定屬性。
var d = document.getElementById('div1');
if (d.hasAttribute('align')) {
d.setAttribute('align', 'center');
}
上面代碼檢查div
節(jié)點是否含有align
屬性。如果有,則設置為居中對齊。
Element.hasAttributes()
Element.hasAttributes
方法返回一個布爾值,表示當前元素是否有屬性,如果沒有任何屬性,就返回false
,否則返回true
。
var foo = document.getElementById('foo');
foo.hasAttributes() // true
Element.removeAttribute()
Element.removeAttribute
方法移除指定屬性。該方法沒有返回值。
// HTML 代碼為
// <div id="div1" align="left" width="200px">
document.getElementById('div1').removeAttribute('align');
// 現在的HTML代碼為
// <div id="div1" width="200px">
dataset 屬性
有時,需要在HTML元素上附加數據,供 JavaScript 腳本使用。一種解決方法是自定義屬性。
<div id="mydiv" foo="bar">
上面代碼為div
元素自定義了foo
屬性,然后可以用getAttribute()
和setAttribute()
讀寫這個屬性。
var n = document.getElementById('mydiv');
n.getAttribute('foo') // bar
n.setAttribute('foo', 'baz')
這種方法雖然可以達到目的,但是會使得 HTML 元素的屬性不符合標準,導致網頁代碼通不過校驗。
更好的解決方法是,使用標準提供的data-*
屬性。
<div id="mydiv" data-foo="bar">
然后,使用元素節(jié)點對象的dataset
屬性,它指向一個對象,可以用來操作 HTML 元素標簽的data-*
屬性。
var n = document.getElementById('mydiv');
n.dataset.foo // bar
n.dataset.foo = 'baz'
上面代碼中,通過dataset.foo
讀寫data-foo
屬性。
刪除一個data-*
屬性,可以直接使用delete
命令。
delete document.getElementById('myDiv').dataset.foo;
除了dataset
屬性,也可以用getAttribute('data-foo')
、removeAttribute('data-foo')
、setAttribute('data-foo')
、hasAttribute('data-foo')
等方法操作data-*
屬性。
注意,data-
后面的屬性名有限制,只能包含字母、數字、連詞線(-
)、點(.
)、冒號(:
)和下劃線(_
)。而且,屬性名不應該使用A
到Z
的大寫字母,比如不能有data-helloWorld
這樣的屬性名,而要寫成data-hello-world
。
轉成dataset
的鍵名時,連詞線后面如果跟著一個小寫字母,那么連詞線會被移除,該小寫字母轉為大寫字母,其他字符不變。反過來,dataset
的鍵名轉成屬性名時,所有大寫字母都會被轉成連詞線+該字母的小寫形式,其他字符不變。比如,dataset.helloWorld
會轉成data-hello-world
。
更多建議: