基礎(chǔ)DOM
DOM的全稱是Document Object Model -> 文檔對象模型屉来,我們可以使用JavaScript來操作DOM腥椒,從而改變改變文檔的結(jié)構(gòu)蟹倾,樣式和內(nèi)容(即網(wǎng)頁顯示的內(nèi)容和樣式)荤崇。DOM 將文檔解析為一個由節(jié)點和對象(包含屬性和方法的對象)組成的結(jié)構(gòu)集合。也就是說DOM就是一個對象被廓,這個對象叫做document。
? 因此我們可以在網(wǎng)頁里打印出整個文檔:
console.log( document )//得到一個對象萝玷,點開這個對象就可以看到整個文檔的結(jié)構(gòu)和內(nèi)容
//document是js自帶的嫁乘,所以不會報錯
? 既然可以在document
里打印出文檔的結(jié)構(gòu),我們就可以獲取并修改球碉。
獲取元素
修改的第一步是獲取蜓斧,先得到,再修改睁冬。
? 獲取元素又這樣的幾個函數(shù):
- document.querySelector('完整css選擇器')
query是查詢的意思挎春,Selector是選擇器的意思看疙,連起來翻譯為:查詢選擇器,document是一個對象直奋,它下邊有一個querySelector屬性能庆,是一個函數(shù),我們把css選擇器(字符串)作為參數(shù)傳遞進去脚线,會返回第一個復(fù)合條件的元素搁胆。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="item list one">123</div>
<div></div>
<div></div>
<div></div>
</body>
<script>
var div = document.querySelector('div')
console.log( div )//<div class="item list one">123</div>
</script>
</html>
? 上例中我們傳入的選擇器是div
,在css里如果用div
選擇邮绿,代表選中所有的div
標(biāo)簽渠旁,而這里querySelector
這個方法,只能返回到匹配的第一項:
<body>
<div></div><!-- 新加了一個div -->
<div class="item list one">123</div>
<div></div>
<div></div>
<div></div>
</body>
<script>
var div = document.querySelector('div')
console.log( div )//<div></div>
</script>
</html>
? 上圖中我們改變了結(jié)構(gòu)之后船逮,返回的內(nèi)容變了顾腊,變成了第一個沒有內(nèi)容的div
。
-
document.querySelectorAll('完整css選擇器')
?
html
結(jié)構(gòu)不變傻唾,和上邊的一樣投慈。var divList = document.querySelectorAll('div') console.log(divList)//NodeList(4) [div.item.list.one, div, div, div] //通過指定下標(biāo),可以獲取到里邊的某一個元素 console.log( divList[0] )//<div class="item list one">123</div>
? 獲取到了頁面中所有的div冠骄。
-
document.getElementById('Id名')
只得到找到的第一個
<body> <div id="box"></div> ... </body> <script> var div = document.getElementById('box') console.log( div )//<div id="box"></div> </script>
document.getElementsByClassName('class名')
得到
<body>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</body>
<script>
var div = document.getElementsByClassName('item')
console.log( div )//HTMLCollection(4) [div.item.list.one, div.item, div.item, div.item]
</script>
? 獲取到了所有類名里有item
的元素伪煤。
- document.getElementsByTagName('標(biāo)簽名')
<body>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</body>
<script>
var div = document.getElementsByClassName('div')
console.log( div )//HTMLCollection(4) [div.item.list.one, div.item, div.item, div.item]
</script>
- document.getElementsByName('name名稱')
通過元素的name屬性來返回找到的一組元素。
<body>
<input name="myInput" type="text" size="20" />
<input name="myInput" type="text" size="20" />
<input name="myInput" type="text" size="20" />
</body>
<script>
var div = document.getElementsByName('myInput')
console.log( div )//NodeList(3) [input, input, input]
</script>
? 上邊獲取元素時凛辣,不管是NodeList
和HTMLCollection
長得都很像數(shù)組抱既,但是他們不是一個數(shù)組,是類數(shù)組扁誓,他們之前的區(qū)別這里暫時還講不到防泵。
? 但js里不是所有的元素都是需要先獲取再使用的,如下幾個就可以直接拿來用:
document.title //文檔的標(biāo)題蝗敢,也就是title標(biāo)簽里的內(nèi)容
document.body //body元素
document.head // head標(biāo)簽
document.documentElement // html標(biāo)簽
? 現(xiàn)在我們有6中方法來獲取元素他們之間有什么區(qū)別呢捷泞?
這些獲取元素的方法分為兩類:靜態(tài)方法和動態(tài)方法,接下來我們看看他們之間的區(qū)別寿谴。
? 要觀察靜態(tài)方法和動態(tài)方法的區(qū)別我們需要先介紹一下innerHTML
:
<body>
<div class="item">
<p>
123
</p>
</div>
</body>
<script>
var div = document.querySelector('.item')
console.log( div )//<div class="item"></div>
console.log( div.innerHTML )//<p>123</p>
//獲取一個元素后通過.innerHTML可以獲取到里邊所有的元素和元素里的內(nèi)容锁右,同時也可以進行修改
div.innerHTML += '<div>456</div>'
console.log( div.innerHTML )//<p>123</p>'<div>456</div>'
</script>
? 接下來我們看看靜態(tài)和動態(tài)方法比較:
<body>
<div class="item"></div>
</body>
<script>
var divOne = document.querySelectorAll('.item'),
divTwo = document.getElementsByClassName('item'),
divThree = document.getElementsByTagName('div')
console.log( divOne )//NodeList [div.item]
console.log( divTwo )//HTMLCollection [div.item]
console.log( divThree )//HTMLCollection [div.item]
document.body.innerHTML += '<div class="item"></div>'
console.log( divOne )//NodeList [div.item]
console.log( divTwo )//HTMLCollection(2) [div.item, div.item]
console.log( divThree )//HTMLCollection(2) [div.item, div.item]
</script>
? 從上例中我們發(fā)現(xiàn),在動態(tài)的給html
文檔中添加元素的時候讶泰,document.querySelectorAll
這種方法不會去動態(tài)的更新咏瑟,而getElementsByClassName
和getElementsByTagName
及時的更新了出來,從原來的獲取到1個變成獲取到了兩個痪署。
? 靜態(tài)方法有:
document.querySelector()
document.querySelectorAll()
? 動態(tài)方法有:
document.getElementById()
document.getElementsByClassName()
document.getElementsByTagName()
document.getElementsByName()
? 改變元素的類名:
我們獲取到一個元素之后码泞,可以通過
.className
來獲取到這個元素的類名,然后對其修改狼犯。
<body>
<div class="item one"></div>
</body>
<script>
var div = document.querySelector('.item')
console.log( div.className )//"item one"
div.className += ' two'//此時我們看到元素的類名里多加了一個two
</script>
? 除此之外還有另外一個查看元素類名的方法:
<font color="red"><b>classList</b></font>
classList返回一個元素的類名屬性類數(shù)組余寥。
<body>
<div class="item one"></div>
</body>
<script>
var item = document.querySelector('.item')
console.log( item.classList )//DOMTokenList(2) ["item", "one", value: "item one"]
console.log( item[0] )//'item'
console.log( item[1] )//'one'
</script>
? classList
下有如下幾個方法給我們用來操作某個元素的類名:
add()
//html和上邊的一樣
item.classList.add('three')
console.log( item.classList )//DOMTokenList(3) ["item", "one", "three", value: "item one three"]
? 上邊我們只添加了一個领铐,如果想添加多個,多穿幾個參數(shù)用逗號隔開就可以了:
item.classList.add('three', 'four')
console.log( item.classList )//DOMTokenList(4) ["item", "one", "three", "four", value: "item one three four"]
remove()
? 除了添加外我們還可以刪除:
console.log( item.classList )//DOMTokenList(4) ["item", "one", "three", "four", value: "item one three four"]
item.classList.remove('four')
console.log( item.classList )//DOMTokenList(3) ["item", "one", "three", value: "item one three"]
? 同樣的我們也可以刪除多個劈狐,參數(shù)之間用逗號隔開:
console.log( item.classList )//DOMTokenList(4) ["item", "one", "three", "four", value: "item one three four"]
item.classList.remove('three','four')
console.log( item.classList )//DOMTokenList(2) ["item", "one", value: "item one"]
replace( oldClass, newClass )
用一個新類名替換已有的類名罐孝。replace翻譯為替換。
console.log( item.classList )//DOMTokenList(2) ["item", "one", value: "item one"]
item.classList.replace('one', 'some')
console.log( item.classList )//DOMTokenList(2) ["item", "some", value: "item some"]
toggle()
有就刪除肥缔,沒有就添加莲兢。toggle也叫做開關(guān)。
console.log( item.classList )//DOMTokenList(2) ["item", "one", value: "item one"]
item.classList.toggle('one')
console.log( item.classList )//DOMTokenList(1) ["item", value: "item"]
item.classList.toggle('one')
console.log( item.classList )//DOMTokenList(2) ["item", "one", value: "item one"]
contains()
console.log( item.classList )//DOMTokenList(2) ["item", "one", value: "item one"]
console.log( item.classList.contains('one') )//true
console.log( item.classList.contains('two') )//false
? 元素的屬性不止有class
還有id
和其他屬性续膳,DOM
為我們提供了幾個可以獲取改艇,查找和設(shè)置元素屬性的函數(shù):
setAttribute('屬性名','屬性值') 設(shè)置屬性
getAttribute('屬性名') 獲取屬性
removeAttribute('屬性名') 刪除屬性
他們會把結(jié)果返回回來坟岔,也就是說我們可以直接打印谒兄,或者拿一個變量接收。
<body>
<div id="box" class="item one"></div>
</body>
<script>
//這個幾個函數(shù)都是用在元素身上的社付,因此需要先獲取到元素承疲。
//假設(shè)下邊的刪除,獲得和修改例子都是獨立的鸥咖,不會相互影響燕鸽。實際上去這樣寫的時候上一步的結(jié)果會影響下一步,具體的可以在代碼中嘗試
var box = document.getElementById('box')
console.log(box)//<div id="box" class="item one"></div>
//獲得
console.log( box.getAttribute('class') )//item one
//和直接點className沒有區(qū)別
console.log( box.ClassName )//item one
//id和直接點id沒有區(qū)別
console.log( box.getAttribute('id') )//box
console.log( box.id )//box
//刪除
console.log( box.removeAttribute('class') )
console.log( box )//<div id="box"></div> class屬性被刪除了
//刪除的時候會有一點不同
box.className = ''//等號是賦值啼辣,可以把class屬性清空但是class屬性還是會顯示在元素上
console.log( box )//<div id="box" class></div>
//設(shè)置
box.setAttribute('title', 'helloworld')//給這個div設(shè)置了一個title屬性啊研,值為title
console.log( box )//<div id="box" class="item one" title="helloworld"></div>
//直接點title
box.title = 'helloworld'
console.log( box )//<div id="box" class="item one" title="helloworld"></div>
</script>
? 上邊我們給元素設(shè)置、查找或者刪除屬性的時候都是元素的自有屬性鸥拧,也就是說元素身上本來就可以有這些屬性党远,但除此之外在開發(fā)中我們會經(jīng)常為元素設(shè)置一些自定義屬性:
所謂自定義屬性就是元素本身沒有這個屬性,但是我們可以自己創(chuàng)造屬性名富弦。
? 例如:
<body>
<div class="box" id="item" abc='hello'></div>
</body>
? 在這個例子中沟娱,class
和id
都是有作用的,我們可以通過css
來給.box
或者#item
設(shè)置樣式腕柜,我們也可以通過getElementsById
或者getElementsByClassName
來獲取到這些元素花沉,貌似abc
就顯得毫無意義,但通過以后的學(xué)習(xí)我們會發(fā)現(xiàn)自定義屬性其實有大用處媳握。
? 既然它也是有用的,那么我們除了直接把自定義屬性寫在標(biāo)簽里外磷脯,可以用js
動態(tài)的獲取蛾找,設(shè)置和刪除嗎?當(dāng)然可以:
依然是使用:
setAttribute('屬性名'赵誓,'屬性值') 設(shè)置屬性
getAttribute('屬性名') 獲取屬性
removeAttribute('屬性名') 刪除屬性
? 注意打毛,如果修改自定義屬性柿赊,非常建議使用這三個函數(shù):
<body>
<div id="box" class="item one"></div>
</body>
<script>
var box = document.getElementById('box')
console.log( box )//<div id="box" class="item one"></div>
//使用點來添加,修改幻枉,清空自定義屬性
box.abc = 'hello'
console.log( box )//<div id="box" class="item one"></div> 我們發(fā)現(xiàn)碰声,abc屬性好像并沒有被設(shè)置上
console.log( box.abc )//'hello'確實可以打印出來
//如果使用set來設(shè)置
box.setAttribute('abc', 'hello')
console.log( box )//<div id="box" class="item one" abc='hello'></div> 這一次我們直接可以在打印box的時候看到他身上有一個abc屬性
//修改沒有什么不同,都可以修改
//刪除熬甫,和類名一樣胰挑,通過box.abc=''只能清空,不能刪除掉abc這個屬性椿肩,而removeAttribute可以
</script>
? 本節(jié)左后一個知識點:
innerText
<body>
<div class="item one">
<p>
123
</p>
<span>
456
</span>
</div>
</body>
<script>
var item = document.querySelector('item')
console.log( item )//把整個item都打印了下來
console.log( item.innerHTML )//<p>123</p><span>456</span>
</script>
? 除此之外我們還有innerText
來打印文本:
console.log(item.innerText)//'1 2 3' 只能打印出item元素里的所有文本瞻颂,不管這些內(nèi)容屬于哪個子元素
//當(dāng)然了獲取的目的是為了操作,我們也可以對其進行操作
item.innerText = 'hello'
console.log(item.innerText)//<div class="item one"></div> 毀天滅地郑象,把老子的p和span標(biāo)簽都給干沒了贡这,就是這么硬核
? 因此我們在使用innerText
的時候,如果只想改變某個元素里的文本內(nèi)容厂榛,就要準(zhǔn)確的指明這個元素:
var p = document.querySelector('.item > p')
console.log( p )//<p>123</p>
p.innerText = 'hello'
console.log( p )//<p>hello</p>
? 他和innerHTML
的區(qū)別:
item.innerHTML = '<div><p>123</p></div>'
console.log( item )//<div class="item one"><div><p>123</p></div></div>
//innerHTML認(rèn)得標(biāo)簽
item.innerText = '<p>123</p>'
//頁面中class為item one的這個div里邊的內(nèi)容直接變成<p>123</p>,p標(biāo)簽沒有被轉(zhuǎn)義盖矫,可以手動在頁面中嘗試
? innerText
吃什么吐什么,innerHTML
認(rèn)得標(biāo)簽击奶。
? 非常完美辈双,但是剛才我們給的都是字符串,假如給其他類型呢正歼?
//Number
p.innerText = 123
console.log(p.innerText)//'123'
//布爾值
p.innerText = true
console.log(p.innerText)//'true'
p.innerText = false
console.log(p.innerText)//'false'
//undefined和null
p.innerText = undefined
console.log(p.innerText)//'undefined'
p.innerText = null
console.log(p.innerText)//'null'
//[]
p.innerText = []
console.log(p.innerText)//''
p.innerText = [1, 2, 3]
console.log(p.innerText)//'1, 2, 3'
//{}
p.innerText = {}
console.log(p.innerText)//'[object Object]'
p.innerText = {a: 1, b: 2}
console.log(p.innerText)//'[object Object]'
? 只要給的不是個字符串辐马,全都轉(zhuǎn)成字符串!