1. 程式人生 > 其它 >JavaScript——BOM操作、DOM操作

JavaScript——BOM操作、DOM操作

JavaScript——BOM操作、DOM操作

一、BOM操作

1.1 window相關操作

/*
	BOM(Browser Object Model)是指瀏覽器物件模型,它使 JavaScript 有能力與瀏覽器進行“對話”
*/
// 1、開啟新視窗
window.open('url','','width=800px,left=200px')
// 2、關閉當前瀏覽器視窗
window.close()
// 3、標識自己是一個瀏覽器(爬蟲中需要使用)
navigator.userAgent
// 4、前進
history.forward()
// 5、後退
history.back()
// 6、獲取當前頁面所在的地址、也可再加賦值符號和網址跳轉
window.location.href()
// 7、重新整理當前頁面
window.location.reload()
// 8、警告框
alert()
// 9、確認框
confirm()
// 10、提示框
prompt()

1.2計時器相關操作 (important)

let time = setTimeout(showMsg,3000)

clearTimeout(time)
setTimeOut(()=>{},延遲時間) 設定一個定時器,時間到後執行回撥函式,只執行一次
可以同時定義多個定時器,定時器回撥函式到期自動執行無需手動呼叫

clearTimeOut(timeOutID) 清除定時器

setInterval(()=>{},間隔時間) 設定一個定時器,每間隔多少時間就執行一次,可以同時定義多個

clearInterval(timeOutID) 清除定時器

1.3 全面總結

# 概念
瀏覽器物件模型,提供了獨立於內容而與瀏覽器視窗進行互動的物件,核心物件是window
DOM頂級物件是document BOM頂級物件是window
BOM比DOM更大,包含DOM
window 包含document location navigation screen history

# 2.window物件
1.它是JS訪問瀏覽器視窗的一個介面
2.它是一個全域性物件,定義在全域性作用域中的變數、函式都會變成window物件的屬性和方法(在呼叫時我們通常省略window)

# 3.視窗載入事件
window.onload=()=>{}
window.addEventListener('load',()=>{})
視窗(頁面)載入事件,當文件內容完全載入完成時會觸發該事件(包括影象,指令碼檔案,CSS檔案等),並呼叫該事件的回撥函式
觸發條件:1.a標籤連結跳轉 2.重新整理 3.前進後退

pageshow事件 在頁面顯示時觸發(比如在火狐瀏覽器內,有個往返快取的特點,此時前進後退無法觸發onload事件,所以使用pageshow事件)
經測試,火狐會前進後退實際會執行onload事件

document.addEventListener('DOMContentloaded',()=>{})
DOMContentLoaded事件觸發時,僅當DOM載入完成,不包括樣式表,圖片,flash等等

如果頁面圖片很多,載入完圖片比較耗時,此時推薦使用DOMContentLoaded事件

# 4.調整視窗大小事件
window.addEventListener('resize',()=>{})
視窗大小每次改變自動觸發

# 5.定時器
setTimeOut(()=>{},延遲時間) 設定一個定時器,時間到後執行回撥函式,只執行一次
可以同時定義多個定時器,定時器回撥函式到期自動執行無需手動呼叫

clearTimeOut(timeOutID) 清除定時器

setInterval(()=>{},間隔時間) 設定一個定時器,每間隔多少時間就執行一次,可以同時定義多個

clearInterval(timeOutID) 清除定時器

# 6.JS同步非同步
1.同步任務都在主執行緒上執行,形成一個執行棧
2.非同步任務通過回撥函式實現,放在一個非同步任務佇列裡面
執行流程:
先執行同步執行棧中的同步任務
非同步任務(回撥函式)放入任務佇列中
執行棧中所有同步任務執行完畢,系統就會按次序讀取任務佇列中的非同步任務的回撥函式
非同步任務的回撥函式進入執行棧開始執行,執行完成後再次讀取任務佇列,看是否有新的回撥函式
主執行緒不斷獲取任務、執行任務、獲取任務、執行任務,這就是事件迴圈(event loop)

# 7.location物件
window物件給我們提供了一個location屬性用於獲取或設定窗體url,並且可以解析url
因為這個屬性返回的是一個物件,所以我們成為location物件

1.URL是網際網路上標準資源的地址。網際網路上每個檔案都有一個唯一的URL,它包含的資訊指出檔案位置以及瀏覽器如何處理它
組成:
protocol 通訊協議:http、ftp、maito等
host 主機名(域名)
port 埠
path 路由
query 引數 以鍵值對形式&符號分開
fragment #後面的內容 常見於連結錨點

2.location物件屬性 location.href 返回整個URL location.host 返回主機域名 port返回埠號
pathname 返回路徑 search 返回引數 hash 返回#後面片段
重點:href 和 search

3.location常見方法
location.assign() 跟href 可以重定向頁面(跳轉頁面)
location.replace() 替換當前頁面
location.reload() 重新載入頁面相當於F5重新整理 裡面引數為true就是強制重新整理(不載入快取直接從伺服器讀取)

# 8.navigator物件
navigator物件包含有關瀏覽器的資訊,它有很多屬性
最常見的是userAgent 該屬性可以返回由客戶機發送伺服器的uer-agent頭部的值

# 9.history物件
history物件 與瀏覽器歷史記錄進行互動 該物件包含使用者在瀏覽器視窗中訪問過的URL
forward() 前進功能
back() 後退功能
go() 前進後退功能

# 10.PC端網頁特效
1.offset系列屬性
element.offsetParent 返回該元素具有定位的父級元素 如果父級都沒有定位則返回body
offsetTop/Left 返回元素相對帶有定位屬性父元素上方/左方偏移
offsetWidth/Height 返回自身包括padding、邊框、內容區的寬度/高度,返回數值不帶單位
offset與style屬性的區別:offset能獲得所有的樣式,style只能獲得行內樣式表的樣式
獲取元素大小使用offset,改變元素樣式使用style

2.client系列
clientTop/Left 返回元素上邊框/左邊框大小
clientHeight/Width 返回元素包括padding、內容區的長寬,不含邊框,返回數值不帶單位

3.立即執行函式
主要用於建立一個獨立作用域,裡面所有變數都是區域性變數
一般來說JS都要先宣告函式再呼叫執行它,而立即執行函式不需要呼叫,直接執行
寫法一 (函式)()
寫法二 ((函式)())

4.scroll系列
scrollTop/Left 返回被捲去的上側/左側距離 返回數值不帶單位
scrollWidth/Height 返回自身實際高度,不含邊框,返回數值不帶單位
(和clinet的區別在於盒子不夠內容超出時,clinet返回盒子的寬高而scroll會把超出部分的內容一起返回)

三個系列主要分別就是帶不帶邊框和內容超出的部分的長度是否顯示

# 11.動畫函式
1.JS動畫原理就是通過setInterval不斷移動盒子
加判定條件關閉定時器,注意此元素需要新增定位才能使用element.style.left/top等

# 12.移動端網頁特效
1.觸屏事件
touchstart 手指觸控到一個DOM元素時觸發
touchmove 手指在一個DOM元素上滑動時觸發
touchend 手指從一個DOM元素上移開時觸發
2.觸控事件物件
touches 正在觸控式螢幕幕的手指的列表
targetTouches 正在觸控當前DOM元素的手指列表
如果偵聽的是一個DOM元素,他們兩個是一樣的
changedTouches 手指狀態發生了改變的列表,從無到有,從有到無變化

最常使用的是e.targetTouches[0],觸控的第一根手指,裡面含有座標等引數

# 13.本地儲存
1.特徵
資料儲存在瀏覽器中
設定、讀取方便,頁面重新整理不丟失資料
容量較大
只能儲存傳統的值,可以將物件JSON.stringfy()編碼後儲存

2.window.sessionStorage
生命週期為關閉瀏覽器視窗
在同一個視窗頁面下資料可以共享
以鍵值對的形式儲存
sesstionStorage.setItem(key,value) 儲存資料
sesstionStorage.getItem(key) 獲取資料
sesstionStorage.removeItem(key) 刪除資料
sesstionStorage.clear() 移除所有資料

3.window.localStorage
永久存在,除非手動刪除
可以多視窗共享
以鍵值對的形式儲存
API同上

二、DOM操作

2.1 概念

	DOM (Document Object Model)是指文件物件模型,通過它可以訪問HTML文件的所有元素

	既然DOM操作是通過js程式碼來操作標籤 所以我們需要先學習如何查詢標籤之後才能給標籤繫結一些JS程式碼(DOM操作)

2.2 查詢標籤

/*
1.js中變數名的命名風格推薦是駝峰體
2.js程式碼查詢到的標籤如果需要反覆使用可以用變數接收 規律 xxxEle
*/
// 結果就是標籤物件本身
document.getElementById('')
// 結果是數組裡面多個標籤物件
document.getElementByClassName('')
document.getElementByTagName('')

// 父節點標籤元素
parentElement
// 所有子標籤
children
// 第一個子標籤
firstElementChild
// 最後一個子標籤
lastElementChild
// 下一個兄弟標籤
nextElementSibling
// 上一個兄第標籤
previousElementSibling

2.3操作節點

// js程式碼建立一個標籤
let aEle = document.createElement('a')
// js程式碼操作標籤屬性 (只能新增預設屬性)
aELe.href = 'url'
// 相容預設屬性和自定義屬性
setAttribute()
getAttribute("")
removeAttrubute("")
// js程式碼操作標籤文字
aELe.innerText = '文字資訊'
// js程式碼查詢div標籤並將a追加進div內部
let divEle = document.getElementByTagName("div")[0]
divEle.appendChild(aEle)

// 獲取標籤內部所有的文字內容
.innerText
// 替換/設定標籤內部的文字(不識別標籤語法)
.innerText = '文字資訊'
// 獲取標籤內部所有的標籤 (包括文字)
.innerHTML
//  替換/設定標籤內部的文字(識別標籤語法)
innerHTML = '文字資訊'

2.4 獲取值的操作

// 針對使用者輸入和使用者選擇的標籤
	標籤物件.value
// 針對使用者上傳的檔案資料
	標籤物件.files
	fileList [檔案物件、檔案物件、檔案物件]
	標籤物件.files[0]  檔案物件

2.5 class與css操作

// 1、 js操作標籤css樣式
標籤物件.style.屬性名
// 2、js操作標籤class屬性
標籤物件.classList.add()
標籤物件.classList.contains()
標籤物件.classList.remove()
標籤物件.classList.toggle()

2.6 事件

// 事件可以簡單的理解為通過js程式碼給html標籤繫結一些自定義的功能
// 常見事件

// 1. 單擊事件
onclick 
// 2. 元素獲取焦點
onfocus
// 3. 元素失去焦點
onblur
// 4. 文字域內容被更改
onchange

// 繫結事件的多種方式
// 方式1
<button onclick=''> </button>
// 方式2
<input type="button" value="按鈕" id='but'>
    <script>
		function showMsg(){
            let msg = prompt('Are you ok?');
            console.log(msg)
        }
        
        let inputEle = document.getElementById('but');
        inputEle.onclick = function(){
            alert("where is who?")
        }
	</script>
<!--事件函式中的this關鍵字-->
<!--
	this指代的就是當前被操作的標籤物件本身
	如果事件函式內有多層巢狀,那麼最好在一開始就用變數儲存一下,防止後續變化

onload方法
	xxx.onload 等待xxx載入完畢之後在執行後面的程式碼
-->

三、事件實戰案例

<input type="text" value="username:" id="userName">
<script>
	let inputEle = document.getElementById('userName')
    inputEle.onfocus = function(){
        this.value = ''
    }
    inputEle.onblur = function(){
        this.value = 'username:'
    }
</script>

<p>
    username:<input type="text" id='userName'>
    <span style='color: red'></span>
</p>

<p>
    password:<input type='password' id='passWord'>
    <span style='color: orange'></span>
</p>

<button id='suBtn'>
    登入
</button>

<script>
//1.查詢提交按鈕的標籤、
    suEle=document.getElementById('suBtn')
// 2.給按鈕標籤繫結點選事件
    subEle.onclick = function(){
        // 3.查詢獲取使用者輸入的標籤並獲取資料
        let userNameEle = document.getElementById('userName')
        let passWordEle = document.getElementById('passWord')
        if(userNameEle.value === 'jason'){
            userNameEle.nextElementSibling.innerText = '使用者名稱不能是jason'
        }
        if(passWordEle.value ==='123'){
            passWord.nextElementSibling.innerText = '密碼不能是123'
        }
    }
</script>
<!--省:-->
<select name="" id="province">
    
</select>

<!--市:-->
<select name="" id="city">
    
</select>

<script>
	let data = {
        "河北": ["廊坊市", "邯鄲市"],
        "北京": ["朝陽區", "海淀區"],
        "山東": ["威海市", "煙臺市"],
        "安徽": ["蕪湖市", "合肥市"],
        "上海": ["浦東新區", "靜安區"]
    }
    
// 提前查詢好省和市的select標籤
    let provinceEle = document.getElementById("province");
    let cityEle = document.getElementById('city');
    // 獲取所有省份資訊
    for (let pro in data) {
        // 建立好option標籤
        let proOpEle = document.creatElement('option');
        // 新增文字以及屬性
        proOpEle.innerText = pro;
        proOpEle.setAttribute('value',pro)
        // 將建立好的option標籤新增到省的下拉框中
        proSeEle.appendChild(proOpEle)
    }
    // 給省標籤繫結文字域變化事件  onchange
    proOpEle.onchange = function(){
        // 每次操作市之前清空市的資料
        cityEle.innerHTML = '';
        // 獲取使用者選擇的省資訊,根據省資訊獲取市資訊
        let targeyProData = this.value;
        let cityDataList = data[targetProData];
        // 迴圈獲取每一個市資訊,建立option標籤,新增到市下拉框中
        for (let i = 0; i < cityDataList.lenth; i++){
            let cityOpEle = document.createElement('option');
            cityOpEle.innerText = cityDataList[i];
            cityOpEle.setAttribute('value',cityDataList[i]);
            cityEle.appendChild(cityOpEle)
        }
    }
</script>

四、DOM總結

 1.DOM (Document Obejct Model),是W3C推薦的處理可擴充套件標記語言的標準程式設計介面,通過DOM介面改變網頁樣式等
DOM樹:
文件:一個頁面就是一個文件,DOM中用document表示
元素:頁面中所有標籤都是元素,DOM中使用element表示
節點:網頁中的所有內容都是節點(標籤,屬性等),DOM中用node表示
DOM把以上所有內容都看作物件

console.dir()列印裡面的物件

# 2.一些獲取元素的方法
getElementById() 通過id名得到某元素

getElementsByTagName() 返回帶有指定標籤名物件的集合 偽陣列形式儲存(即便只有一個元素或者沒有對應元素也是以偽陣列形式儲存)
element.getElementsByTagName() 從指定元素獲取元素內部標籤物件的集合


getElementByClassName() 通過類名獲得某元素集合

querySelect 返回指定選擇器(id選擇器,類選擇器,標籤選擇器)的第一個元素物件
document.querySelect(".div1")

querySelectAll() 返回指定選擇器的所有元素物件(偽陣列)

# 3.獲取特殊元素的方法
document.body 獲取body元素
document.documentElemeny 獲取html元素

# 4.事件處理
事件是可以被JS檢測到的一種行為
事件由3部分組成 事件源 事件型別 事件處理程式
事件源:事件被觸發的物件
事件型別:如何觸發
事件處理程式: 通過一個函式賦值的方式完成

執行事件的步驟
1.獲取事件源
2.註冊事件(繫結事件)
3.新增事件處理程式

除了onclick還有許多滑鼠事件,可以自行查詢相關API

# 5.操作元素
1.元素裡面的innerHTML和innerText屬性可以改變元素內部的內容
innerHTML和innerText的區別:
前面一個識別html標籤 後一個不識別如div.innerHTML="<p>你好</p>"
前面一個讀取時會把HTML標籤一起讀取下來 後一個讀取時只讀取文字

2.改變元素其他屬性
title src id 等等都可以改變

3.操作表單元素屬性 利用DOM可以操作的表單元素的屬性:type、value、checked、selected、disabled

4.操作元素大小、顏色、位置等(更改樣式產生的是行內樣式,權重比style高)
element.style 行內樣式操作 (樣式比較少或功能簡單使用style屬性)
element.className 類名樣式操作(其實就是先定義好類的樣式,再通過JS改獲取的元素的類名讓它擁有樣式)
示例:element.style.backgroundColor="red"

5.獲取元素的屬性
element.屬性
element.getAttribute('屬性') (可以用來獲取自定義屬性)
element.setAttribute('屬性','值') (用來更改自定義屬性,原生屬性也能改)
element.removeAttribute('屬性')(移除屬性)

操作元素隱藏顯示 在於元素的style的display屬性

表單元素的獲取焦點和失去焦點事件 onfocus onblur

總結:操作元素是DOM的核心部分
1.操作元素內容
2.操作普通元素屬性
3.操作表單元素屬性
4.操作元素樣式 className element.style

自定義屬性:
H5規定自定義屬性以data-開頭作為屬性名並且賦值 如:data-index=1
設定自定義屬性可以在標籤上新增或者element.setAttribute()
H5新增獲取自定義屬性的方法 element.dataset.自定義屬性(記得去除data-) 如 div.dataset.index

# 6.DOM 節點操作
獲取元素有兩種方式:
利用DOM提供的方法獲取元素 利用節點層級獲取元素

利用節點父兄子關係獲取元素:邏輯性強,相容性稍差
網頁中所有內容都是節點

節點一般擁有nodeType nodeName nodeValue三個屬性 nodeType是規定好的
元素節點 nodeType為1
屬性節點 nodeType為2
文字節點(包含空格換行等) nodeType為3
實際操作時通常只用的是元素節點

1.element.parentNode 拿到離元素最近的父節點

2.element.childNodes 拿到元素所有的子節點包括文字節點(一般不提倡)
element.children (非標準)拿到元素的所有子元素節點

3.element.firstElementChild 拿到子節點的第一個元素節點
element.lastElementChild 最後一個元素節點(這兩個API只支援IE9以上)
實際開發中我們使用element.children[0]和element.children[element.children.length-1]拿到第一個或最後一個元素節點

4.element.nextSibling 下一個兄弟節點
element.nextElementSibling element.previousElementSibling 下一個或上一個元素兄弟節點

5.document.createElement("")建立一個節點
element.appendChild(child)新增一個子節點
element.insertBefore(child,指定元素) 指定元素指某個已經存在的子元素 將child插在它的前面

6.node.removeChild(parent
.) 刪除一個子節點並返回此節點

7.node.cloneNode() 複製一個節點並返回此節點 括號引數為空 則只拷貝此節點,不拷貝里面的內容
括號內部為true,則將節點本身以及內部子節點一起拷貝

三種動態建立元素的區別
document.write() 會導致頁面重繪 element.innnerHTML 建立多個元素效率會更高 document.createElement("") 第三種效率最好使用最多

## DOM重點核心
W3C組織推薦的處理可標記語言的標準程式設計介面,W3C已經定義了一系列的DOM介面,通過操作這些介面可以改變網頁的內容和樣式
對於DOM操作,我們主要針對於元素的操作,實現建立、增、刪、改、查、屬性操作、樣式操作、事件操作

# 7.事件高階
1.註冊事件的兩種方式 :傳統方式和方法監聽註冊事件
傳統註冊方式 <button onlick="alert('你好')">或onlcik=...
特點 註冊事件的唯一性 後一個註冊事件會覆蓋前一個

2.方法監聽註冊方式
特點 同一個元素同一個事件可以註冊多個監聽器,可以觸發多個事件
elementTarget.addEventListener('type',listener[,useCapture])
type 為型別
listener 為事件處理函式
useCapture 為一個布林值 預設為false

3.刪除事件(解綁事件)
傳統方式 btn.onclick=()=>{alert("1);btn.onclick=null;}
方法監聽刪除事件 elementTarget.removeEventListener('type',listener[,useCapture])

4.DOM事件流
事件流描述的是從頁面中接收事件的順序
事件發生時會在元素節點之間按照特定的順序傳播,這個傳播過程即DOM事件流
捕獲階段 很少使用
冒泡階段
onclick和attachEvent只能得到冒泡階段 addEventListener第三個引數如果是true,表示在事件捕獲階段呼叫事件處理程式
如果是false 表示在事件冒泡階段呼叫事件處理程式

onblur onfocus onmouseenter onmouoseleave沒有冒泡階段

5.事件物件
div.onclick = funtion(event){}
event就是一個事件物件 寫到偵聽函式的小括號裡面
事件物件只有有了事件才會存在 是系統給我們自動建立的 不需要我們傳遞引數
事件物件 我們事件的一系列相關資料的集合 跟事件相關的 滑鼠事件就包含了滑鼠座標等 鍵盤事件就包含了鍵盤事件的資訊

事件物件的相容性問題 ie678通過 window.event相容性寫法

事件物件的常見屬性和方法
e.target 返回觸發事件的物件(元素)
e.type 返回觸發事件的型別 如click
e.preventDefault() 阻止事件預設行為,如不讓連結跳轉
e.stopPropagation() 阻止冒泡

6.事件委託
利用事件冒泡的原理,如多個子元素含有事件,直接將事件繫結在父元素上,並且使用父元素的事件物件來區分每個子元素觸發時的不同事件處理效果

7.常用滑鼠事件
onclick
onmouseover(滑鼠經過觸發) 和onmouseenter事件的區別:
mouseover經過自身盒子會觸發,經過子盒子還會觸發,mouseenter只會在經過自身盒子時觸發,原因:一個會冒泡另一個不會
onmouseout(滑鼠離開觸發)
onfocus(獲得滑鼠焦點)
onblur(失去滑鼠焦點)
onmousemove(滑鼠移動)
onmouseup(滑鼠彈起)
onmousesedown(滑鼠按下)

contextmenu(控制何時顯示滑鼠右鍵選單),主要和阻止預設事件共同使用阻止某段話被右鍵開啟選單等
selectstart(滑鼠開始選中),可以完全阻止某個元素內容被選中

8.滑鼠事件物件
e.clientX/Y 滑鼠相對於瀏覽器視窗可視區的X/Y座標
e.pageX/Y 滑鼠對於文件介面的X/Y座標(重要)
e.screenX/Y 滑鼠對於電腦桌面的X/Y座標

跟隨滑鼠移動的人物案例:
用mousemove為document註冊滑鼠移動事件,用事件物件拿到滑鼠座標,並同時更改圖片的絕對定位值

9.常用鍵盤事件
onkeyup 某個鍵盤按鍵被鬆開時觸發
onkeydown 某個鍵盤按鍵被按下時觸發
onkeypress 某個滑鼠按鍵被按下時觸發(不識別功能鍵如ctrl shift等)
在鍵盤事件物件中可以拿到對應的鍵,e.key拿到鍵 e.keyCode拿到鍵對應的ASCII碼值