BOM與DOM之DOM操作
一:DOM操作
1.DOM介紹
DOM 是一套對文檔的內容進行抽象和概念化的方法。
當網頁被加載時,瀏覽器會創建頁面的文檔對象模型(Document Object Model)。
HTML DOM 模型被構造為對象的數。
- DOM樹的概念
2.DOM標準規定HTML文檔中的每個成分都是一個節點(node):
- 文檔節點(document對象):代表整個文檔
- 元素節點(element 對象):代表一個元素(標籤)
- 文本節點(text對象):代表元素(標籤)中的文本
- 屬性節點(attribute對象):代表一個屬性,元素(標籤)才有屬性
- 注釋是注釋節點(comment對象)
總結:所有的標籤都可以稱之為是節點
JavaScript 可以通過DOM創建動態的 HTML:
JavaScript 能夠改變頁面中的所有 HTML 元素
JavaScript 能夠改變頁面中的所有 HTML 屬性
JavaScript 能夠改變頁面中的所有 CSS 樣式
JavaScript 能夠對頁面中的所有事件做出反應
3.DOM操作需要用關鍵字
.document
二:查找標籤
1.id查找 類查找 標籤查找(直接查找)
document.getElementById : 根據id獲取一個標籤
document.getElementsByClassName : 根據class屬性獲取
document.getElementsByTagName : 根據標籤名獲取標籤合集
2.id查詢
注意三個方法的返回值是不一樣的
document.getElementById('d1') # id查詢(唯一)
輸出結果:
<div id="d1">…</div>
3.類查詢(多個標籤對象返回數組)
document.getElementsByClassName('c1') # 返回數組
輸出結果:
HTMLCollection [p.c1]0: p.c1length: 1__proto__: HTMLCollection
注意:
Element與Elements區別
s : 代表查詢多個元素
4.標籤查詢(多個標籤對象返回 數組)
document.getElementsByTagName('div') # 數組
輸出結果:
HTMLCollection(3) [div#d1, div, div, d1: div#d1]
5.索引取值方法(獲取標籤數組內容)
document.getElementsByTagName('div')[1]
輸出結果:
<div>div>div</div>
6.變量名 存儲方法(標籤內索引取值內容)
let divEle = document.getElementsByTagName('div')[1]
# 打印變量
divEle
輸出結果:
<div>div>div</div>
7.注意:(存儲變量名)
當你用變量名指代標籤對象的時候 一般情況下都推薦你書寫成(見名知意)
以下示例:
xxxEle
divEle
aEle
pEle
- HTML代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="d2">div
<div>div>div</div>
<p class="c1">div>p
<span>div>p>span</span>
</p>
<p>div>p</p>
</div>
<div>div+div</div>
</body>
</html>
三:間接查找(熟悉)
1.簡介查找
parentElement 父節點標籤元素
children 所有子標籤
firstElementChild 第一個子標籤元素
lastElementChild 最後一個子標籤元素
nextElementSibling 下一個兄弟標籤元素
previousElementSibling 上一個兄弟標籤元素
2.生成變量名 (存儲變量名)
let pEle = document.getElementsByClassName('c1')[0]
3.拿父節點(找父標籤)
pEle.parentElement
輸出結果:
<div id="d1">"div
"<div>div>div</div><p class="c1">…</p><p>div>p</p></div>
1.找父標籤的父標籤
pEle.parentElement.parentElement
輸出結果:
<body>…</body>
2.父標籤的父標籤的父標籤
pEle.parentElement.parentElement.parentElement
輸出結果:
<html lang="en"><head>…</head><body>…</body></html>
3.父標籤的父標籤的父標籤的父標籤
pEle.parentElement.parentElement.parentElement.parentElement
輸出結果:
null
4.獲取所有的子標籤(找所有的兒子)
# 變量名(存儲)
let divEle = document.getElementById('d2')
打印輸出所以子標籤
divEle.children
5.兩種方法 索引0 獲取第一個標籤(大兒子)
divEle.children[0]
輸出結果:
<div>div>div</div>
6.獲取大兒子
divEle.firstElementChild
輸出結果:
<div>div>div</div>
7.獲取小兒子
divEle.lastElementChild
輸出結果:
<p>div>p</p>
8.同級別下面第一個(弟弟)
divEle.nextElementSibling
輸出結果:
<div>div下面div</div>
9.同級別上面第一個(哥哥)
divEle.previousElementSibling
輸出結果:
<div>div上面的div</div>
- HTML代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>div上面的div</div>
<div>div上面的div</div>
<div id="d2">div
<div>div>div</div>
<p class="c1">div>p
<span>div>p>span</span>
</p>
<p>div>p</p>
</div>
<div>div下面div</div>
<div>div下面div</div>
</body>
</html>
四:節點操作
1.需求
1.通過DOM操作動態的創建img標籤
2.並且給標籤加屬性
3.最後將img標籤追加到div標籤尾部文本中
2.創建img標籤
臨時操作(刷新丟失)
1.創建標籤
let imgEle = document.createElement('img')
2.給標籤設置默認的屬性
imgEle.src = '111.png'
"111.png"
3.打印標籤
imgEle
<img src="111.png">
2.注意:錯誤的方式(自定義屬性沒辦法點的方法設置)
imgEle.username = 'jason' # 自定義的屬性沒辦法點的方式直接設置
"jason"
imgEle
<img src="111.png">
3.解決自定義設置屬性:
1.既可以設置自定義的屬性也可以設置默認的書寫
imgEle.setAttribute('username','jason')
undefined
2.打印標籤
imgEle
<img src="111.png" username="jason">
4.自定義的屬性
imgEle.setAttribute('title','一張圖片')
打印標籤
imgEle
<img src="111.png" username="jason" title="一張圖片">
5.變量名(存儲標籤)
let divEle = document.getElementById('d1')
輸出結果:
undefined
標籤內部添加元素(尾部追加)
divEle.appendChild(imgEle)
輸出結果:
<img src="111.png" username="jason" title="一張圖片">
- 注意:
臨時生效,刷新即失效
HTML代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="d1">div
<p id="d2">div>p</p>
<span>div>span</span>
</div>
</body>
</html>
###### 6.創建a標籤
###### 6.1需求
“`
1.創建a標籤 設置屬性 設置文本
2.添加到標籤內部
3.指定將a標籤塞在p標籤上面
“`
###### 7.創建a標籤(添加到標籤內部)實踐操作
“`
1.創建a標籤
let aEle = document.createElement(‘a’)
打印結果
aEle
2.設置標籤默認屬性
aEle.href = ‘//www.mzitu.com/’
“//www.mzitu.com/”
打印結果
aEle
<a href=”https://www.mzitu.com/”>
3.給標籤設置文本內容
aEle.innerText = ‘點我有你好看!’
“點我有你好看!”
打印結果
aEle
<a href=”https://www.mzitu.com/”>點我有你好看!
4.獲取id為d1的位置
let divEle = document.getElementById(‘d1’)
undefined
5.獲取id為d2的位置
let pEle = document.getElementById(‘d2’)
undefined
6.添加標籤內容指定位置添加(將a標籤添加到div的內部p標籤的上面)
divEle.insertBefore(aEle,pEle)
<a href=”https://www.mzitu.com/”>點我有你好看!

###### 8.額外補充
appendChild() : 標籤內添加元素(尾部追加)
了解:
removeChild() : 移出一個子節點
replaceChild() : 替換
setAttribute() 設置屬性
了解
getAttribute() 獲取屬性
removeAttribute() 移除屬性
#### 五:innerText與innerHTML的區別
###### 1.對比innerText與innerHTML的區別
divEle.innerText # 獲取標籤內部所有的文本
輸出結果:
“div 點我有你好看!
div>p
div>span”
divEle.innerHTML # 內部文本和標籤都拿到
輸出結果:
“div
點我有你好看!
div>p
div>span“
對比innerText與innerHTML區別
divEle.innerText = ‘heiheihei’
“heiheihei”
divEle.innerHTML = ‘hahahaha’
“hahahaha”
divEle.innerText = ‘
heiheihei
‘ # 不識別html標籤
“
heiheihei
“
divEle.innerHTML = ‘
hahahaha
‘ # 識別html標籤
“
hahahaha
“
###### 2.總結innerText與innerHTML區別
innerText : 只能獲取標籤內部的文本 設置文本的時候不識別HTML標籤
innerHTML : 文本和標籤都獲取 設置文本的時候識別HTML標籤
#### 六:獲取值操作value
###### 1.獲取用戶數據標籤內部的數據
let seEle = document.getElementById(‘d2’)
seEle.value
“111”

seEle.value
“333”

let inputEle = document.getElementById(‘d3’)
變量名需要靠value取值
inputEle.value

###### 2.獲取用戶上傳的文件數據
let fileEle = document.getElementById(‘d4’)
注意:點value無法獲取到文件數據(錯誤取值)
fileEle.value
‘C:\fakepath\新建 DOC 文檔.doc’

注意:錯誤取值(拿到文件對象)
fileEle.files # 數組 [文件對象,文件對象1…]
FileList {0: File, length: 1}
0: File {name: ‘新建 DOC 文檔.doc’, lastModified: 1642843676639, lastModifiedDate: Sat Jan 22 2022 17:27:56 GMT+0800 (中國標準時間), webkitRelativePath: ”, size: 9216, …}
length: 1
###### 3.獲取文件數據(需要靠索引取值)
fileEle.files[0]
File {name: ‘新建 DOC 文檔.doc’, lastModified: 1642843676639, lastModifiedDate: Sat Jan 22 2022 17:27:56 GMT+0800 (中國標準時間), webkitRelativePath: ”, size: 9216, …}
lastModified: 1642843676639
lastModifiedDate: Sat Jan 22 2022 17:27:56 GMT+0800 (中國標準時間)

<details>
<summary>HTML代碼</summary>
“`
#### 七:class,css操作
###### 1.class操作
“`
1.生成變量名對象
let divEle = document.getElementById(‘d1’)
undefined
2.獲取標籤所有的類屬性
divEle.classList
DOMTokenList(3) [“c1”, “bg_red”, “bg_green”, value: “c1 bg_red bg_green”]

3.移除某個類屬性
divEle.classList.remove(‘bg_red’)
undefined

4.驗證是否包含某個類屬性
divEle.classList.contains(‘c1’)
true
divEle.classList.contains(‘c2’)
false

5.有則刪除無則添加
divEle.classList.toggle(‘bg_red’)
false # 有則刪除 返回false

divEle.classList.toggle(‘bg_red’)
true # 無則添加 返回true

###### 2.css操作 只要想操作標籤css先用style起手(DOM操作操作標籤樣式)
* (操作樣式時 統一先用style起手(操作標籤樣式))
###### 1.生成變量名對象
let pEle = document.getElementsByTagName(‘p’)[0]
undefined
###### 2.字體顏色
pEle.style.color = ‘red’
“red”

###### 3.字體大小
pEle.style.fontSize = ’28px’
“28px”
注意:
會將css中橫杆或者下劃線去掉 然後講後面的單詞變大寫
font-size fontSize

###### 4.背景
pEle.style.backgroundColor = ‘yellow’
“yellow”

###### 5.邊框
pEle.style.border = ‘3px solid red’
“3px solid red”

<details>
<summary>HTML代碼</summary>
難得在一起 大家玩的盡興
“`
#### 八:事件
###### 1.介紹
“`
HTML 4.0的新特性之一是有能力使HTML事件觸發瀏覽器中的動作(action),比如當用戶點擊某個HTML元素時啟動一段javaScript。下面是一個屬性列表,這些屬性可插入HTML標籤來定義事件動作。
“`
###### 2.什麼是事件?
“`
達到某個事先設定的條件自動觸發的動作就叫做事件
“`
###### 3.抽象比喻
“`
比如你踩着地雷會爆炸 : 該現象就可以叫做事件
正如你所敲的鍵盤會有對應的反應 : 該現象就可以叫做事件
“`
###### 4.常用事件
“`
onclick : 當用戶點擊某個對象時調用的事件句柄。
ondblclick 當用戶雙擊某個對象時調用的事件句柄。
onfocus 元素獲得焦點。 // 練習:輸入框
onblur 元素失去焦點。 應用場景:用於表單驗證,用戶離開某個輸入框時,代表已經輸入完了,我們可以對它進行驗證.
onchange 域的內容被改變。 應用場景:通常用於表單元素,當元素內容被改變時觸發.(select聯動)
onkeydown 某個鍵盤按鍵被按下。 應用場景: 當用戶在最後一個輸入框按下回車按鍵時,表單提交.
onkeypress 某個鍵盤按鍵被按下並鬆開。
onkeyup 某個鍵盤按鍵被鬆開。
onload 一張頁面或一幅圖像完成加載。
onmousedown 鼠標按鈕被按下。
onmousemove 鼠標被移動。
onmouseout 鼠標從某元素移開。
onmouseover 鼠標移到某元素之上。
onselect 在文本框中的文本被選中時發生。
onsubmit 確認按鈕被點擊,使用的對象是form。
###### 九:事件實踐操作 綁定事件的兩種方式(標籤查找與函數查找)
###### 1.事件案例(按鈕觸發事件)
// 當用戶點擊該按鈕會觸發事件調用func1()
// 按鈕
// 該標籤本身沒有任何的事件 通過script內標籤查找
// 按鈕
“`
2.案例2(sctipt代碼放到head內)
我們將sctipt代碼放到head內進行測試,再次測試是否正常
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
// 第一種綁定事件的方式
function func1() {
alert(111)
}
// 第二種
// 1.先通過標籤查找找到(d1)標籤
let btnEle = document.getElementById('d1');
// 2.然後給b1標籤綁定事件,用戶點擊會觸發函數體運行
btnEle.onclick = function () {
alert(222)
}
</script>
</head>
<body>
<button onclick="func1()">點我</button> // 按鈕
<button id="d1">點我</button> // 按鈕
</body>
</html>
3.報錯原因(注意)
原因:
代碼執行是從上往下的,執行到該代碼體時,未查找到標籤,因為d1標籤還未渲染到 所以綁定時報錯。
注意:
js代碼script標籤既可以放在html頁面head內 也可以放在body內
一般情況下都是放在body內最下方(底部)
4.事件案例3(預加載onload實現標籤查找在head內)
1.實現head內執行標籤查找運行,使用預加載(onload)
2. 等待瀏覽器窗口加載完畢之後再執行代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
<!-- 等待頁面加載完畢之後再執行代碼-->
window.onload = function () {
// 第一種綁定事件的方式
function func1() {
alert(111)
}
// 第二種
let btnEle = document.getElementById('d1');
btnEle.onclick = function () {
alert(222)
}
}
</script>
</head>
<body>
<button onclick="func1()">點我</button> # 按鈕
<button id="d1">點我</button> # 按鈕
</body>
</html>
5.函數報錯原因:
原因:
該方法等待頁面加載完畢在執行script代碼,驗證了可以執行標籤查找,但是函數調用報錯了,因為先執行頁面代碼,函數調用失敗,找不到被調用函數即報錯。
解決方法:
使用第二種方法即可標籤查找
6.總結(標籤查找與函數查找):
標籤查找 : 通常使用標籤查找式,同一份代碼可以給多個標籤綁定式
函數查找 : func()函數方法太局限性了,要寫很多代碼
推薦使用標籤查找方式
7.window.onload
當我們給頁面上的元素綁定事件的時候,必須等到文檔加載完畢。因為我們無法給一個不存在的元素綁定事件。
window.onload事件在文件加載過程結束的時候觸發。此時,文檔中的所有對象都位於DOM中,並且所有圖像,腳本,鏈接和子框架都已完成加載。
注意:.onload()函數存在覆蓋現象。
十:原生js事件綁定
1.開關燈案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1 {
height: 400px;
width: 400px;
border-radius: 50%;
}
.bg_black {
background-color: black;
}
.bg_red {
background-color: red;
}
</style>
</head>
<body>
<div id="d1" class="c1 bg_red bg_black"></div>
<button id="d2">變色</button>
<script>
<!--給d2按鈕綁定事件-->
// 先找到d2按鈕
let btnEle = document.getElementById('d2')
// 拿到d1標籤
let divEle = document.getElementById('d1')
// 綁定點擊事件
btnEle.onclick = function () {
// 動態修改div標籤的類屬性(有則移出無則添加)
divEle.classList.toggle('bg_red')
// 用戶點擊按鈕 判斷div內是否有bg_red屬性
}
</script>
</body>
</html>
2.input框獲取焦點失去焦點案例
1.什麼是獲取焦點與失去焦點?
獲取焦點 : 鼠標放在input框內
失去焦點 : 鼠標移出input框內
2.初級版input框 獲取焦點與失去焦點
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" value="歡迎光臨 《恆運集團》" id="d1">
<script>
// 先找到input框id
let iEle = document.getElementById('d1')
// 獲取焦點事件(鼠標放在input框內)
iEle.onfocus = function () {
// 將input框內部的值去除
iEle.value = ''
// 點value就是獲取 符號賦值就是設置
}
// 失去焦點事件(鼠標移出input框內)
iEle.onblur = function () {
// 給input標籤重寫賦值
iEle.value = '歡迎下次光臨 《恆運集團》'
}
</script>
</body>
</html>
3.注意:
iEle.value : 獲取屬性值
iEle.value = '' : 修改值屬性(設置)
4.進階版 input框實時展示當前時間
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" id="d1">
<script>
// 獲取標籤id
let inputEle = document.getElementById('d1')
// 1 訪問頁面之後 將訪問的時間展示到input框中
function showTime() {
// 生成日期對象
let currentTime = new Date();
// 設置賦值屬性 Date轉成當地時間
inputEle.value = currentTime.toLocaleString()
}
// 每隔一秒執行一次函數
setInterval(showTime, 1000)
</script>
</body>
</html>
5.終極版 input框實時展示當前時間(增加 按鈕 開 關)
6.需求
// 1 訪問頁面之後 將訪問的頁面展示到input框中
// 2 動態展示當前時間
// 3 頁面上加兩個按鈕 一個開始 一個結束
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#d1 {
text-align: center;
}
</style>
</head>
<body>
<input type="text" id="d1" style="display: block;height: 50px;width: 200px">
<button id="d2">開始</button>
<button id="d3">結束</button>
<script>
// 先定義一個全局存儲定時器的變量
let t = null
// 獲取標籤d1
let inputEle = document.getElementById('d1')
// 獲取標籤d2
let startBtnEle = document.getElementById('d2')
// 獲取標籤d3
let endBtnEle = document.getElementById('d3')
// 1 訪問頁面之後 將訪問的時間展示到input框中
function showTime() {
// 生成日期對象
let currentTime = new Date();
// 設置賦值屬性 Date轉成當地時間
inputEle.value = currentTime.toLocaleString()
}
// 開始執行實時展示時間
startBtnEle.onclick = function () {
// 判斷t是否為空(為空執行 不為空不執行)取反
if(!t){
// 每隔一秒執行一次函數
t = setInterval(showTime, 1000) // 每次點擊一次就會開設一個定時器 而t只指代最後一個
// 定時器賦值給全局變量
}
}
// 停止展示實時時間
endBtnEle.onclick = function () {
// 清除t指代的定時器
clearInterval(t)
t = null
}
</script>
</body>
</html>
7.省市聯動 現實選擇省市地址
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<select name="" id="d1">
// selected : 選擇 disabled : 禁用
<option value="" selected disabled>--請選擇省--</option> // 選項
</select>
<select name="" id="d2"></select>
<script>
// 獲取標籤d1(省)
let proEle = document.getElementById('d1')
// 獲取標籤d2(市)
let cityEle = document.getElementById('d2')
// 先模擬省市數據
data = {
"河北": ["廊坊", "邯鄲",'唐山'],
"北京": ["朝陽區", "海淀區",'昌平區'],
"山東": ["威海市", "煙台市",'臨沂市'],
'上海':['浦東新區','靜安區','黃浦區'],
'深圳':['南山區','寶安區','福田區']
};
// 選for循環獲取省
for(let key in data){
// 將省信息做成一個個option標籤 添加到第一個select框中
// 1 創建option標籤
let opEle = document.createElement('option')
// 2 設置文本
opEle.innerText = key
// 3 設置value
opEle.value = key // <option value="省">省</option>
// 4 將創建好的option標籤添加到第一個select中
proEle.appendChild(opEle)
}
// 文本域變化事件 文本變化自動觸發change事件(變化) js標準格式on
proEle.onchange = function () {
// 先獲取到用戶選擇的省
let currentPro = proEle.value
// 獲取對應的市信息
let currentCityList = data[currentPro]
// 清空上一次市select中所有的option(防止市數據錯亂)
cityEle.innerHTML = ''
// 創建選項 並賦值
let ss = "<option disabled selected>請選擇</option>"
// 設置文本標籤
cityEle.innerHTML = ss
// // 創建option標籤 = 選項
// let oppEle = document.createElement('option')
// // option設置文本
// oppEle.innerText = '請選擇'
// // 設置自定義屬性
// oppEle.setAttribute('selected','disabled')
// for循環打印所有市 渲染到第二個select中
for (let i=0;i<currentCityList.length;i++){
// 獲取value市
let currentCity = currentCityList[i]
// 1 創建option標籤
let opEle = document.createElement('option')
// 2 設置文本
opEle.innerText = currentCity
// 3 設置value
opEle.value = currentCity // option value='市'>市</option>
// 4 將創建好的option標籤添加到第一個select中
cityEle.appendChild(opEle)
}
}
</script>
</body>
</html>