JavaScript擴(kuò)展DOM、BOM、AJAX、事件、定時(shí)器舉例詳解
BOM 操作
BOM
指的是瀏覽器對(duì)象模型:Browser Object Mode
,通過操作 window
對(duì)象的屬性和方法來實(shí)現(xiàn)與瀏覽器的交互。
BOM
的構(gòu)成如下圖所示:
其中,window
對(duì)象是頂級(jí)對(duì)象,在 window
對(duì)象下面有一些重要的屬性:
document
:DOM 對(duì)象。location
:用于獲取或設(shè)置文檔當(dāng)前 URL 的位置。navigation
:包含瀏覽器配置相關(guān)的信息。history
:用于操作瀏覽器的歷史記錄。screen
:用于獲取屏幕設(shè)備信息。用戶操作
警告框:
alert(message)
對(duì)話框:
const res = confirm(message) // 根據(jù)用戶點(diǎn)擊確定或取消結(jié)果:true或者false
彈出輸入對(duì)話框(
defaultValue
為默認(rèn)值占位值,可選):prompt(message, defaultValue) // 返回值為用戶的輸入文本 // 參考實(shí)例 const res = prompt('請(qǐng)輸入姓名:', 'Alice') console.log('用戶的輸入結(jié)果:', res)
獲取窗口尺寸
window
對(duì)象包含一些存儲(chǔ)窗口尺寸的只讀屬性:
屬性 | 描 述 |
---|---|
innerWidth | 窗口的內(nèi)部寬度 |
innerHeight | 窗口的內(nèi)部高度 |
outerWidth | 整個(gè)瀏覽器窗口的寬度 |
outerHeight | 整個(gè)瀏覽器窗口的高度 |
參考用例:
console.log('窗口的內(nèi)部寬度:', innerWidth) // 1797 console.log('窗口的內(nèi)部高度:', innerHeight) // 889 console.log('整個(gè)瀏覽器窗口的寬度:', outerWidth) // 1797 console.log('整個(gè)瀏覽器窗口的高度:', outerHeight) // 976
獲取屏幕尺寸
訪問 window
對(duì)象的 screen
屬性會(huì)返回一個(gè) Screen
對(duì)象,它包含一些屏幕尺寸相關(guān)的只讀屬性:
屬性 | 描 述 |
---|---|
screen.width | 屏幕的寬度 |
screen.height | 屏幕的高度 |
screen.availWidth | 屏幕上可用的寬度 |
screen.availHeight | 屏幕上可用的高度(不包括任務(wù)欄) |
參考實(shí)例:
console.log('屏幕的寬度:', screen.width) // 1797 console.log('屏幕的高度:', screen.height) // 1011 console.log('屏幕上可用的寬度:', screen.availWidth) // 1797 console.log('屏幕上可用的高度:', screen.availHeight) // 976
Location 對(duì)象
訪問 window
對(duì)象的 location
屬性會(huì)返回一個(gè) Location
對(duì)象,它包含有關(guān)文檔當(dāng)前 URL 位置的信息。
屬性 | 描 述 |
---|---|
location.href | 包含整個(gè) URL 的字符串 |
location.protocol | 包含 URL 協(xié)議方案的字符串 |
location.hostname | 包含 URL 域名的字符串 |
location.pathname | 包含開頭的 / 后跟 URL 路徑的字符串 |
location.search | 包含開頭的 ? 后跟 URL 的“查詢字符串” |
location.hash | 包含開頭的 # 后跟 URL 的片段標(biāo)識(shí)符 |
參考用例:
console.log('整個(gè) URL:', location.href) console.log('URL 協(xié)議:', location.protocol) console.log('URL 域名:', location.hostname) console.log('URL 路徑:', location.pathname)
此外,Location
對(duì)象還包含對(duì) URL 進(jìn)行操作的方法。
其中,assign()
方法可以使瀏覽器加載并顯示指定 URL 處的頁面:
location.assign(url)
reload()
方法會(huì)重新加載當(dāng)前 URL,就像點(diǎn)擊了刷新按鈕一樣。
location.reload()
History 對(duì)象
訪問 window
對(duì)象的 history
屬性會(huì)返回一個(gè) History
對(duì)象,可以通過它操作瀏覽器的歷史記錄。
方法 | 描 述 |
---|---|
location.go() | 移動(dòng)到歷史記錄中相對(duì)于當(dāng)前頁面的位置,例如 -1 表示上一頁,1 表示下一頁。參數(shù)為 0 則會(huì)重新加載當(dāng)前頁面。 |
location.back() | 轉(zhuǎn)到歷史記錄中的上一頁,相當(dāng)于點(diǎn)擊瀏覽器的“后退”按鈕 |
location.forward() | 轉(zhuǎn)到歷史記錄中的下一頁,相當(dāng)于點(diǎn)擊瀏覽器的“前進(jìn)”按鈕 |
location.pushState() | 向?yàn)g覽器的歷史記錄中添加一個(gè)條目 |
location.replaceState() | 修改當(dāng)前歷史記錄條目 |
DOM 操作
DOM 的英文全稱為 Document Object Model(文檔對(duì)象模型),它是瀏覽器為每個(gè)窗口內(nèi)的 HTML 頁面在內(nèi)存中創(chuàng)建的表示文檔的結(jié)構(gòu)。通過 DOM,我們可以使用 JavaScript 來對(duì)頁面中的元素進(jìn)行操作。
常用的 DOM 屬性
常用的 DOM 屬性如下表所示:
屬性 | 描 述 |
---|---|
document.title | 獲取文檔的標(biāo)題文本 |
document.URL | 獲取文檔的 URL |
document.head | 獲取文檔的 <head> 元素 |
document.body | 獲取文檔的 <body> 元素 |
document.forms | 獲取文檔的 <form> 元素列表 |
document.images | 獲取文檔的 <img> 元素列表 |
document.links | 獲取文檔的 <a> 元素列表 |
document.scripts | 獲取文檔的 <script> 元素列表 |
常用的 DOM 方法
我們可以使用下面這些方法從當(dāng)前文檔中獲取元素節(jié)點(diǎn):
方法 | 描 述 |
---|---|
document.getElementById() | 通過 id 屬性獲取元素 |
document.getElementsByClassName() | 通過 class 屬性獲取元素列表 |
document.getElementsByTagName() | 通過標(biāo)簽名獲取元素列表 |
document.getElementsByName() | 通過 name 屬性獲取元素列表 |
document.querySelector() | 通過選擇器獲取第一個(gè)匹配的元素 |
document.querySelectorAll() | 通過選擇器獲取所有匹配的元素列表 |
除了獲取已有的元素節(jié)點(diǎn),我們還可以使用下面這些方法創(chuàng)建新節(jié)點(diǎn):
方法 | 描 述 |
---|---|
document.createElement() | 創(chuàng)建元素節(jié)點(diǎn) |
document.createTextNode() | 創(chuàng)建文本節(jié)點(diǎn) |
基本 DOM 操作
常用的元素節(jié)點(diǎn)屬性如下表所示:
屬性 | 描 述 |
---|---|
parentElement | 獲取父級(jí)元素 |
previousElementSibling | 獲取同級(jí)的前一個(gè)元素 |
nextElementSibling | 獲取同級(jí)的后一個(gè)元素 |
children | 獲取子級(jí)元素列表 |
firstElementChild | 獲取第一個(gè)子級(jí)元素 |
lastElementChild | 獲取最后一個(gè)子級(jí)元素 |
常用的元素節(jié)點(diǎn)方法如下表所示:
方法 | 描 述 |
---|---|
cloneNode() | 返回當(dāng)前節(jié)點(diǎn)的副本(如果傳入一個(gè)參數(shù) true 則連同后代節(jié)點(diǎn)一起復(fù)制) |
remove() | 刪除當(dāng)前節(jié)點(diǎn)本身 |
removeChild(node) | 從當(dāng)前節(jié)點(diǎn)的子級(jí)列表中刪除子級(jí)節(jié)點(diǎn) node |
replaceWith(node1, node2, ...) | 將當(dāng)前節(jié)點(diǎn)替換為一組其它節(jié)點(diǎn)或文本 |
prepend(node1, node2, ...) | 在當(dāng)前節(jié)點(diǎn)的子級(jí)列表開頭添加一組新的子級(jí)節(jié)點(diǎn)或文本 |
append(node1, node2, ...) | 在當(dāng)前節(jié)點(diǎn)的子級(jí)列表末尾添加一組新的子級(jí)節(jié)點(diǎn)或文本 |
before(node1, node2, ...) | 在當(dāng)前節(jié)點(diǎn)的前面添加一組新的同級(jí)節(jié)點(diǎn)或文本 |
after(node1, node2, ...) | 在當(dāng)前節(jié)點(diǎn)的后面添加一組新的同級(jí)節(jié)點(diǎn)或文本 |
insertBefore(node, reference) | 在子級(jí)節(jié)點(diǎn) reference 的前面插入一個(gè)新節(jié)點(diǎn) node |
元素節(jié)點(diǎn)的方法參考以下示例:
在這個(gè)示例中:
- 使用
remove()
方法刪除了id="js"
的<li>
元素。 - 創(chuàng)建了一個(gè)新的
<li>
元素,并插入到id="css"
的<li>
元素的前面。 - 在
<h2>
元素的前面添加了一行文本。 - 將
<h2>
元素復(fù)制,并添加到<body>
元素內(nèi)部的末尾位置。
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> </head> <body> <h2>Web 開發(fā)三劍客</h2> <ul> <li id="html">HTML</li> <li id="css">CSS</li> <li id="js">JavaScript</li> </ul> <script> // 刪除元素節(jié)點(diǎn) const js = document.getElementById('js') js.remove() // 創(chuàng)建元素節(jié)點(diǎn) const es = document.createElement('LI') es.prepend('ES6') // 插入新節(jié)點(diǎn) const ul = document.getElementsByTagName('ul')[0] const css = document.getElementById('css') ul.insertBefore(es, css) // 在節(jié)點(diǎn)的前面添加文本 const h2 = document.getElementsByTagName('h2')[0] h2.before('Vue 是一套用于構(gòu)建用戶界面的漸進(jìn)式框架。') // 復(fù)制節(jié)點(diǎn)并在 body 中添加 const clone = h2.cloneNode(true) document.body.append(clone) </script> </body> </html>
預(yù)覽效果:
定時(shí)器
js
中定時(shí)器有一次性定時(shí)器和重復(fù)執(zhí)行定時(shí)器。
一次性定時(shí)器
全局 setTimeout()
函數(shù)設(shè)置一個(gè)定時(shí)器,一旦倒計(jì)時(shí)完成,就會(huì)執(zhí)行一段指定的代碼。
需要注意,定時(shí)器函數(shù)一般為異步函數(shù)。
設(shè)置定時(shí)器的方法如下:
// 使用格式: setTimeout(functionRef, delay, param1, param2, /* …, */ paramN) // 參考示例: setTimeout(() => { console.log('延遲一秒') }, 1000) console.log('其他代碼')
setTimeout()
函數(shù)的返回值是一個(gè)正整數(shù)值,它代表了這個(gè)定時(shí)器的 ID。我們可以將這個(gè)值傳遞給 clearTimeout()
函數(shù)以取消定時(shí)。
// 參考示例: const timer1 = setTimeout(() => { console.log('延遲一秒') }, 1000) const timer2 = setTimeout(() => { console.log('延遲兩秒') }, 2000) const timer3 = setTimeout(() => { console.log('延遲三秒') }, 3000) // 取消第二個(gè)定時(shí)器 clearTimeout(timer2)
重復(fù)定時(shí)器
全局 setInterval()
函數(shù)設(shè)置一個(gè)定時(shí)器,用于重復(fù)執(zhí)行一段指定的代碼,每次執(zhí)行之間有固定的時(shí)間間隔。
其使用格式如下:
// 使用方法: setInterval(functionRef, delay, param1, param2, /* …, */ paramN) // 參考示例: setInterval(() => { console.log('重復(fù)執(zhí)行') }, 1000) console.log('其他代碼')
本地存儲(chǔ)
本地存儲(chǔ)是指在客戶端存儲(chǔ)數(shù)據(jù)。HTML5 為我們提供了兩種 API,分別是 localStorage
與 sessionStorage
。二者的使用方法類似,都可以用來存儲(chǔ)客戶端臨時(shí)信息,并且二者存儲(chǔ)的數(shù)據(jù)格式均為 key/value 對(duì)的形式。
localStorage API
localStorage
對(duì)象是 HTML 5 新增的特性,主要用于本地存儲(chǔ)。
在網(wǎng)絡(luò)發(fā)展的早期,當(dāng)沒有其他選擇時(shí),cookie 被用于一般客戶端數(shù)據(jù)存儲(chǔ)目的。而在現(xiàn)在,更加推薦使用 localStorage
等現(xiàn)代存儲(chǔ) API。
localstorage
與 cookie
主要有以下區(qū)別:
localStorage
解決了早期使用cookie
存儲(chǔ)遇到的存儲(chǔ)空間不足的問題( 每條cookie
的存儲(chǔ)空間為 4k )localStorage
一般瀏覽器支持的是 5M 大小,具體存儲(chǔ)大小根據(jù)瀏覽器的不同會(huì)有所不同。- 相較于
cookie
而言,localStorage
中的信息不會(huì)被傳輸?shù)椒?wù)器。
localStorage
對(duì)象提供的方法如下:
方法 | 說明 |
---|---|
setItem(key, value) | 保存數(shù)據(jù)到本地存儲(chǔ) |
getItem(key) | 根據(jù)指定 key 從本地存儲(chǔ)中獲取數(shù)據(jù) |
removeItem(key) | 根據(jù)指定 key 從本地存儲(chǔ)中移除數(shù)據(jù) |
clear() | 清除所有保存數(shù)據(jù) |
存儲(chǔ)數(shù)據(jù)
localStorage.setItem(key, value) // 方法一 localStorage.key = value // 方法二,和方法一效果一樣
讀取數(shù)據(jù)
localStorage.getItem(key) // 方法一 localStorage.key // 方法二,等效于前者
刪除數(shù)據(jù)
// 根據(jù)指定名稱從本地存儲(chǔ)中移除 localStorage.removeItem(key)
上面的
key
一般是一個(gè)字符串。
清空數(shù)據(jù)
// 清除本地存儲(chǔ)中所有數(shù)據(jù) localStorage.clear()
sessionStorage API
localStorage
和 sessionStorage
對(duì)象作為 HTML5 新增的特性,都可以用來存儲(chǔ)客戶端臨時(shí)信息,并且二者存儲(chǔ)的數(shù)據(jù)格式均為 key/value 鍵值對(duì)數(shù)據(jù)。
sessionStorage
對(duì)象提供的方法與 localStorage
對(duì)象相同,具體如下:
方法 | 說明 |
---|---|
setItem(key, value) | 保存數(shù)據(jù)到本地存儲(chǔ) |
getItem(key) | 根據(jù)指定 key 從本地存儲(chǔ)中獲取數(shù)據(jù) |
removeItem(key) | 根據(jù)指定 key 從本地存儲(chǔ)中移除數(shù)據(jù) |
clear() | 清除所有保存數(shù)據(jù) |
那么localStorage
和 sessionStorage
二者有什么區(qū)別呢?
它們的區(qū)別在于:
localStorage
的生命周期是永久的,除非用戶清除localStorage
信息,否則這些信息將永遠(yuǎn)存在。sessionStorage
的生命周期是臨時(shí)的,一旦當(dāng)前窗口或標(biāo)簽頁被關(guān)閉了,那么通過它存儲(chǔ)的數(shù)據(jù)也就被清空了。
由于具體的調(diào)用方法和localStorage
完全一致,使用方法這里省略。
事件處理
事件是指用戶進(jìn)行了某些操作時(shí)觸發(fā)的“信號(hào)”,例如點(diǎn)擊鼠標(biāo)、按下鍵盤、輸入文字等。我們可以綁定相應(yīng)的事件處理函數(shù)來進(jìn)行處理。
- DOM 0 級(jí)事件與 DOM 2 級(jí)事件
- 鼠標(biāo)事件
- 鍵盤事件
- 表單事件
- 事件對(duì)象
DOM 0 級(jí)事件
DOM 0 級(jí)事件是直接使用 HTML 屬性或 DOM 對(duì)象屬性來指定相應(yīng)的事件處理函數(shù)。例如,click
是當(dāng)鼠標(biāo)點(diǎn)擊時(shí)會(huì)觸發(fā)的事件。我們可以在 HTML 標(biāo)簽里直接寫 onclick
屬性或者在 JavaScript 中使用 onclick = function(){}
。
直接將節(jié)點(diǎn)的onclick
綁定為一個(gè)函數(shù),點(diǎn)擊事件就只能執(zhí)行一個(gè)函數(shù)。但如果添加事件監(jiān)聽,就能同時(shí)執(zhí)行多個(gè)事件所綁定的函數(shù)。
// 直接綁定 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> </head> <body> <input id="btn" type="button" value="按鈕" onclick="alert('歡迎來到藍(lán)橋云課')" /> <script> const el = document.getElementById('btn') el.onclick = function () { alert('你好!藍(lán)橋') } el.onclick = function () { alert('嗨!藍(lán)橋') } // 再次綁定就會(huì)被覆蓋 </script> </body> </html>
DOM 2 級(jí)事件
DOM 2 級(jí)事件可以綁定多個(gè)事件處理函數(shù)。所有的 DOM 節(jié)點(diǎn)都有兩個(gè)方法,分別是 addEvenetListener()
和 removeEventListener()
。
語法格式:
target.addEvenetListener(type, listener) // 添加事件 target.removeEventListener(type, listener) // 移出事件
listener
是一個(gè)函數(shù),如果要移除他需要保證removeEventListener
中傳入的是同一個(gè)函數(shù)名。
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> </head> <body> <input id="btn" type="button" value="按鈕" /> <script> const btn = document.getElementById('btn') btn.addEventListener('click', handler) function handler() { alert('已點(diǎn)擊') btn.removeEventListener('click', handler) } </script> </body> </html>
執(zhí)行后的效果如下:
鼠標(biāo)事件
常用的鼠標(biāo)事件如下表所示:
事件 | 說明 |
---|---|
click | 鼠標(biāo)點(diǎn)擊事件 |
mousedown | 鼠標(biāo)按下事件 |
mouseup | 鼠標(biāo)松開事件 |
mouseover | 鼠標(biāo)移入事件 |
mouseout | 鼠標(biāo)移出事件 |
mousemove | 鼠標(biāo)移動(dòng)事件 |
click 事件
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> <style> div { width: 200px; height: 200px; background-color: #b8b5ff; } </style> </head> <body> <div id="item"></div> <script> const el = document.getElementById('item') // 鼠標(biāo)點(diǎn)擊 el.addEventListener('click', function () { el.style.background = '#ffefa1' }) </script> </body> </html>
mousedown、mouseup 事件
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> <style> div { width: 200px; height: 200px; background-color: #b8b5ff; } </style> </head> <body> <div id="item"></div> <script> const el = document.getElementById('item') // 鼠標(biāo)按下 el.addEventListener('mousedown', function () { el.style.background = '#ffefa1' }) // 鼠標(biāo)松開 el.addEventListener('mouseup', function () { el.style.background = '#b8b5ff' }) </script> </body> </html>
mouseover、mouseout 事件
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> <style> div { width: 200px; height: 200px; background-color: #b8b5ff; } </style> </head> <body> <div id="item"></div> <script> const el = document.getElementById('item') // 鼠標(biāo)移入 el.addEventListener('mouseover', function () { el.style.background = '#ffefa1' }) // 鼠標(biāo)移出 el.addEventListener('mouseout', function () { el.style.background = '#b8b5ff' }) </script> </body> </html>
鍵盤事件
常用的鍵盤事件有以下兩個(gè):
事件 | 說明 |
---|---|
keydown | 鍵盤按下會(huì)觸發(fā)的事件 |
keyup | 鍵盤松開會(huì)觸發(fā)的事件 |
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> </head> <body> <input type="text" value="請(qǐng)輸入內(nèi)容" id="phone" /> <script> const el = document.getElementById('phone') // 鍵盤按下 el.addEventListener('keydown', function () { el.style.color = '#00adb5' }) // 鍵盤松開 el.addEventListener('keyup', function () { el.style.color = '#000000' }) </script> </body> </html>
表單事件
在 JavaScript 中,常用表單事件如下表所示:
事件 | 說明 |
---|---|
focus | 表單元素聚焦時(shí)觸發(fā)的事件 |
blur | 表單元素失焦時(shí)觸發(fā)的事件 |
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> </head> <body> 姓名:<input type="text" id="username" value="輸入你的名字" /> <script> const el = document.getElementById('username') // 當(dāng)聚焦到該輸入框時(shí),把輸入框的內(nèi)容置為空,并設(shè)置字體顏色為藍(lán)色 el.addEventListener('focus', function () { if (el.value == '輸入你的名字') { el.value = '' } el.style.color = '#77acf1' }) // 當(dāng)失去焦點(diǎn)時(shí),顯示輸入框的默認(rèn)內(nèi)容 el.addEventListener('blur', function () { if (el.value == '') { el.value = '輸入你的名字' } el.style.color = '#000000' }) </script> </body> </html>
事件對(duì)象
事件函數(shù)默認(rèn)能接受到一個(gè)可選參數(shù):事件對(duì)象,通過事件對(duì)象可以得到更多關(guān)于該類型事件的信息。例如鼠標(biāo)事件可以拿到鼠標(biāo)的位置坐標(biāo),鍵盤事件能拿到對(duì)應(yīng)按下的鍵。
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> </head> <body> <input id="btn" type="button" value="按鈕" /> <script> const el = document.getElementById('btn') el.addEventListener('click', function (ev) { console.log(`這是一個(gè) ${ev.type} 事件`) // 在控制臺(tái)打印事件類型 }) </script> </body> </html>
鼠標(biāo)事件對(duì)象
鼠標(biāo)事件處理函數(shù)接收到的鼠標(biāo)事件對(duì)象還包含一些其它屬性:
屬性 | 說明 |
---|---|
button | 觸發(fā)鼠標(biāo)事件時(shí)按下的按鈕 |
clientX | 鼠標(biāo)指針在窗口可視區(qū)域中的 X 坐標(biāo) |
clientY | 鼠標(biāo)指針在窗口可視區(qū)域中的 Y 坐標(biāo) |
pageX | 鼠標(biāo)指針相對(duì)于整個(gè)頁面的 X 坐標(biāo)(考慮滾動(dòng)條) |
pageY | 鼠標(biāo)指針相對(duì)于整個(gè)頁面的 Y 坐標(biāo)(考慮滾動(dòng)條) |
movementX | 鼠標(biāo)指針相對(duì)于上次 mousemove 事件位置的 X 坐標(biāo) |
movementY | 鼠標(biāo)指針相對(duì)于上次 mousemove 事件位置的 Y 坐標(biāo) |
參考以下示例:
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> <style> div { width: 200px; height: 200px; background-color: #b8b5ff; } </style> </head> <body> <div id="item"></div> <script> const el = document.getElementById('item') el.addEventListener('click', function (ev) { console.log('頁面中鼠標(biāo)指針的 X 坐標(biāo):', ev.pageX) console.log('頁面中鼠標(biāo)指針的 Y 坐標(biāo):', ev.pageY) }) </script> </body> </html>
鍵盤事件對(duì)象
鍵盤事件處理函數(shù)接收到的鍵盤事件對(duì)象包含一些按鍵信息相關(guān)的屬性:
屬性 | 說明 |
---|---|
code | 鍵盤上的按鍵的代碼值 |
key | 按鍵產(chǎn)生的字符(考慮大小寫) |
shiftKey | 是否按下 Shift 鍵 |
ctrlkey | 是否按下 Ctrl 鍵 |
altkey | 是否按下 Alt 鍵 |
參考以下示例:
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> </head> <body> <input type="text" id="item" /> <p id="msg"></p> <script> const el = document.getElementById('item') el.addEventListener('keydown', function (ev) { // 判斷是否按下 Ctrl 鍵 if (ev.ctrlKey) { msg.innerHTML = '請(qǐng)不要按下 Ctrl 鍵' msg.style.color = 'red' } else { // 當(dāng)沒有按下 Ctrl 鍵時(shí),輸出按鍵產(chǎn)生的字符 msg.innerHTML = '按鍵產(chǎn)生的字符:' + ev.key msg.style.color = 'black' } }) </script> </body> </html>
AJAX
AJAX 的英文全稱為 Asynchronous JavaScript And XML,其中 Asynchronous 是異步的意思。
何為異步呢?它是指通過 AJAX 向服務(wù)器請(qǐng)求數(shù)據(jù),在不刷新整個(gè)頁面的情況下,更新頁面上的部分內(nèi)容。
其工作原理圖如下所示:
使用AJAX
請(qǐng)求的功能如果餐廳中的服務(wù)員,能在不阻塞主要流程的情況下,讓服務(wù)員幫你去做某件事情。如果這件事情你自己去做的話,就會(huì)阻塞你的事件進(jìn)程了。
常用的三種AJAX
:
- XMLHttpRequest API
- Fetch API
- Axios
XMLHttpRequest API
為了通過 AJAX 異步請(qǐng)求數(shù)據(jù),一種傳統(tǒng)的方法是使用 XMLHttpRequest API。
創(chuàng)建 AJAX 的基本步驟如下:
- 創(chuàng)建 XMLHttpRequest 對(duì)象
const httpRequest = new XMLHttpRequest()
- 向服務(wù)器發(fā)送請(qǐng)求
// 規(guī)定發(fā)送請(qǐng)求的一些要求 httpRequest.open(method, url, async) // 將請(qǐng)求發(fā)送到服務(wù)器 httpRequest.send()
open()
方法中的參數(shù)說明如下:
method
:請(qǐng)求的類型,常見的有GET
和POST
。url
:請(qǐng)求的 URL 地址。async
(可選):設(shè)置同步或者異步請(qǐng)求,其值為布爾類型,默認(rèn)為true
。當(dāng)為true
時(shí),使用異步請(qǐng)求;當(dāng)為false
時(shí),使用同步請(qǐng)求。
- 獲取服務(wù)器響應(yīng)狀態(tài)我們使用 HTTP 請(qǐng)求數(shù)據(jù)后,會(huì)反饋給我們相應(yīng)的請(qǐng)求狀態(tài)。我們使用
onreadystatechange
去檢查響應(yīng)的狀態(tài),當(dāng)httpRequest.readyState
為 4 并且httpRequest.status
等于 200 時(shí),說明數(shù)據(jù)請(qǐng)求成功。
其使用如下:
// 檢查響應(yīng)的狀態(tài) httpRequest.onreadystatechange = function () { if (httpRequest.readyState === 4) { if (httpRequest.status == 200) { // 請(qǐng)求成功執(zhí)行的代碼 } else { // 請(qǐng)求失敗執(zhí)行的代碼 } } }
新建一個(gè) index.html
文件,在 <script>
標(biāo)簽內(nèi)寫入以下內(nèi)容:
const xhr = new XMLHttpRequest() // 規(guī)定發(fā)送請(qǐng)求的一些要求 xhr.open('GET', 'https://jsonplaceholder.typicode.com/users', true) // 將請(qǐng)求發(fā)送到服務(wù)器 xhr.send() // 檢查響應(yīng)的狀態(tài) xhr.onreadystatechange = function () { console.log(xhr.readyState) console.log(xhr.status) if (xhr.readyState === 4) { if (xhr.status == 200) { // 請(qǐng)求成功執(zhí)行的代碼 console.log('請(qǐng)求成功') console.log(JSON.parse(xhr.responseText)) } else { // 請(qǐng)求失敗執(zhí)行的代碼 console.log('請(qǐng)求失敗') } } }
輸出結(jié)果如下:
在控制臺(tái)中輸出的 200
是 HTTP 的響應(yīng)狀態(tài)碼,該狀態(tài)碼還有其他取值,可以閱讀 HTTP response status codes 了解更多。
而穿插在 200
之后的數(shù)字 2
、3
、4
是 readyState
屬性的值,它的取值有以下幾種:
0
代表未初始化請(qǐng)求。1
代表已與服務(wù)器建立連接。2
代表請(qǐng)求被接受。3
代表請(qǐng)求中。4
代表請(qǐng)求完成。
Fetch API
Fetch API 提供了用于通過網(wǎng)絡(luò)獲取資源的接口,它是 XMLHttpRequest API 的更強(qiáng)大、更靈活的替代品。其使用方式如下:
const response = await fetch(url)
其中,fetch()
是一個(gè)全局函數(shù),它接收要請(qǐng)求的 URL 作為參數(shù),并返回一個(gè) Promise
對(duì)象。
該異步操作的結(jié)果是一個(gè) Response
對(duì)象,我們可以使用 await
關(guān)鍵字獲取。它提供了多種方法來解析不同格式的正文內(nèi)容:
arrayBuffer()
:二進(jìn)制數(shù)據(jù)。blob()
:二進(jìn)制數(shù)據(jù)。formData()
:HTML 表單數(shù)據(jù)。json()
:JSON 格式數(shù)據(jù)。text()
:純文本數(shù)據(jù)。
下面是一個(gè)基本的使用示例:
async function getData() { const response = await fetch('https://jsonplaceholder.typicode.com/users') if (!response.ok) { // 請(qǐng)求失敗執(zhí)行的代碼 console.log('請(qǐng)求失敗') } else { // 請(qǐng)求成功執(zhí)行的代碼 console.log('請(qǐng)求成功') const json = await response.json() console.log(json) } } getData()
默認(rèn)情況下,fetch()
發(fā)出 GET 請(qǐng)求,但我們可以使用 method
選項(xiàng)來使用不同的請(qǐng)求方式:
async function getData() { const response = await fetch('https://jsonplaceholder.typicode.com/posts', { method: 'POST', body: JSON.stringify({ title: 'foo', body: 'bar', userId: 1 }), headers: { 'Content-type': 'application/json; charset=UTF-8' }, }) if (!response.ok) { // 請(qǐng)求失敗執(zhí)行的代碼 console.log('請(qǐng)求失敗') } else { // 請(qǐng)求成功執(zhí)行的代碼 console.log('請(qǐng)求成功') const json = await response.json() console.log(json) } } getData()
在上面的代碼中:
method
選項(xiàng)用于設(shè)置請(qǐng)求方式。body
選項(xiàng)用于設(shè)置發(fā)送到服務(wù)器的內(nèi)容。headers
選項(xiàng)用于設(shè)置 HTTP 請(qǐng)求頭。
Axios
一個(gè)非常主流的AJAX
的封裝插件—— Axios
。
Axios 是一個(gè)基于 Promise 語法的、用于瀏覽器和 Node.js 的 HTTP 庫。簡(jiǎn)單的理解就是對(duì) AJAX 的封裝,且具有易用、簡(jiǎn)潔、高效等特點(diǎn)。
它本身具備以下功能:
- 可以從瀏覽器中創(chuàng)建 XMLHttpRequest。
- 能從 Node.js 創(chuàng)建 HTTP 請(qǐng)求。
- 支持 Promise API。
- 能夠攔截請(qǐng)求和響應(yīng)。
- 可以轉(zhuǎn)換請(qǐng)求和響應(yīng)數(shù)據(jù)。
- 可以取消請(qǐng)求。
- 可以自動(dòng)轉(zhuǎn)換 JSON 數(shù)據(jù)。
- 在客戶端支持防止 CSRF/XSRF 攻擊。
為了使用 Axios,我們需要使用 <script>
標(biāo)簽進(jìn)行引入:
<script src="https://unpkg.com/axios@1.7.7/dist/axios.min.js"></script>
新建一個(gè) test.json
文件,并寫入以下數(shù)據(jù),作為接下來使用 Axios 請(qǐng)求的數(shù)據(jù)文件:
{ "msg": "Hello Axios!" }
新建一個(gè) index.html
文件,寫入以下內(nèi)容:
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>文檔</title> <!-- 引入 Axios 的 CDN --> <script src="https://unpkg.com/axios@1.7.7/dist/axios.min.js"></script> </head> <body> <script> axios.get('./test.json').then((res) => { console.log(res) }) </script> </body> </html>
在上面代碼中,我們使用 Axios 發(fā)送一個(gè)簡(jiǎn)單的 AJAX 請(qǐng)求,用于獲取 test.json
中的數(shù)據(jù),并輸出在控制臺(tái)。
可以看到,通過 Axios 獲取到的數(shù)據(jù)實(shí)際上是一個(gè)對(duì)象,真正需要的數(shù)據(jù)是該對(duì)象的 data
屬性值。
上面這個(gè)例子只是 Axios 眾多使用方式中的一種,它主要是用于執(zhí)行 GET 請(qǐng)求。
下面我們看幾個(gè)它比較常用的使用方式:
- 執(zhí)行 GET 數(shù)據(jù)請(qǐng)求:
axios .get('url', { params: { id: '接口配置參數(shù)(相當(dāng)于url?id=xxxx)', }, }) .then(function (res) { console.log(res) // 處理成功的函數(shù) 相當(dāng)于 success }) .catch(function (error) { console.log(error) // 錯(cuò)誤處理 相當(dāng)于 error })
- 執(zhí)行 POST 數(shù)據(jù)請(qǐng)求并發(fā)送數(shù)據(jù)給后端:
axios .post( 'url', { data: {} }, { headers: 'xxxx', // 頭部配置 } ) .then(function (res) { console.log(res) // 處理成功的函數(shù) 相當(dāng)于 success }) .catch(function (error) { console.log(error) // 錯(cuò)誤處理 相當(dāng)于 error })
- 通用方式(適用于任何請(qǐng)求方式):
//-------- GET --------// axios({ method: 'get', url: 'xxx', cache: false, params: { id: 123, }, headers: 'xxx', }) //-------- POST --------// axios({ method: 'post', url: 'xxx', data: { firstName: 'Tom', lastName: 'Sun', }, })
其中需要注意的是,GET 和 POST 請(qǐng)求中向后端傳遞參數(shù)的配置項(xiàng)名字不同:GET 請(qǐng)求需要使用 params
,POST 請(qǐng)求需要使用 data
發(fā)送數(shù)據(jù)。
作為一個(gè)獨(dú)立的強(qiáng)大的 HTTP 庫,Axios 的功能遠(yuǎn)不止這些,可以通過 Axios 的官網(wǎng)學(xué)習(xí)。
總結(jié)
到此這篇關(guān)于JavaScript擴(kuò)展DOM、BOM、AJAX、事件、定時(shí)器的文章就介紹到這了,更多相關(guān)js擴(kuò)展DOM、BOM、AJAX、事件、定時(shí)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
TypeScript環(huán)境搭建的實(shí)現(xiàn)步驟
本文主要介紹了TypeScript環(huán)境搭建的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01關(guān)于JS數(shù)據(jù)類型檢測(cè)的多種方式總結(jié)
Javascript中檢查數(shù)據(jù)類型一直是老生常談的問題,類型判斷在web開發(fā)中也有著非常廣泛的應(yīng)用,所以下面這篇文章主要給大家介紹了關(guān)于JS數(shù)據(jù)類型檢測(cè)的那些事,需要的朋友可以參考下2021-09-09JavaScript中???、??=、?.和?||的區(qū)別淺析
在?JS?中,???運(yùn)算符被稱為非空運(yùn)算符,下面這篇文章主要給大家介紹了關(guān)于JavaScript中???、??=、?.和?||區(qū)別的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08element?UI中在?el-select?與?el-tree?結(jié)合組件實(shí)現(xiàn)過程
項(xiàng)目上實(shí)現(xiàn)某個(gè)功能,使用到了?el-select?和?el-tree?組合實(shí)現(xiàn),記錄下兩者結(jié)合的實(shí)現(xiàn)過程,對(duì)?el-select?與?el-tree?結(jié)合組件實(shí)現(xiàn)過程感興趣的朋友跟隨小編一起看看吧2023-02-02JavaScript在IE中“意外地調(diào)用了方法或?qū)傩栽L問”
FF是正常的,IE報(bào)“意外地調(diào)用了方法或?qū)傩栽L問”。2008-11-11使用控制臺(tái)破解百小度一個(gè)月只準(zhǔn)改一次名字
這篇文章主要介紹了使用控制臺(tái)破解百小度一個(gè)月只準(zhǔn)改一次名字的方法和代碼,有需要的小伙伴可以參考下。2015-08-08