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