在大多的Web頁面或Web應用程序中,構建UI僅僅是其中小小的一部分,其中有些U是純靜態的,但有些UI是會隨著用戶的操作帶來相應變化的。愛掏網 - it200.com比如,用戶通過鼠標點擊,鍵盤按下,視窗大小調整或一系列其他的手勢和交互來觸發。愛掏網 - it200.com而這些我們往往稱之為事件。愛掏網 - it200.com在Web中處理事件都是交給JavaScript來完成,同樣的,在React中也有相應的事件。愛掏網 - it200.com在這一節開始,我們就來學習React中的事件。愛掏網 - it200.com
你可能在DOM的世界中對事件的使用有一定的了解。愛掏網 - it200.com如果沒有,也不用擔心,我們在開啟探討React的事件之前會對JavaScript中的事件做一個初步的了解。愛掏網 - it200.com
Web頁面或Web應用程序總是會提供一些控件給用戶操作的。愛掏網 - it200.com簡單地說,用戶做了一個操作,會發生什么。愛掏網 - it200.com或者說,應用程序用什么方法讓它們對已知的事件作出反應。愛掏網 - it200.com
在開始之前,我們必須了解事件是什么?這個很簡單,在Web中創建的所有東西都可以通過以下的語句來建模:
在Web中我們可以用無數種不同的方法來填補這句話中的空白之處。愛掏網 - it200.com第一個()
表示發生了什么?第二個()
描述相應的操作會發生什么?比如下面這些例子:
- 當(頁面加載)完成時,請(播放視頻)
- 當(點擊)發生時,請(提交表單)
- 當(鼠標釋放)時,請(放大圖片)
- 當(按下刪除鍵)時,請將此(列表項刪除)
- 當(觸摸手勢)發生時,請將(舊照片過濾掉)
- 當(文件下載)完時,請(更新進度條)
這種模型適用于我們所有的編碼。愛掏網 - it200.com不過,事件只不過是一個信號。愛掏網 - it200.com它表示剛剛發生了什么事。愛掏網 - it200.com而這個事件是可以鼠標點擊、鍵盤按下、觸摸手勢等。愛掏網 - it200.com回到我們所說的事件模型中,模型的前半部分是我們所說的事件,后面部分是事件反應:
用到我們生活中來的話,有點類似于我們發送了一個信號,等事物接到這個信號就會做出一個對應的響應。愛掏網 - it200.com而且在JavaScript中,事件又是非常重要的。愛掏網 - it200.com如果用專業術語來描述的話,其包含兩個部分:
- 事件偵聽
- 事件做出的反應
這兩個步驟看起來非常簡單,但是不要忘記這是在JavaScript中處理。愛掏網 - it200.com如果我們稍微走錯了一步,都會給我們的應用程序帶來巨大的創傷。愛掏網 - it200.com
事件偵聽
在JavaScript中有三種方式可以為DOM元素注冊事件處理函數(即給元素添加事件偵聽)。愛掏網 - it200.com
addEventListener
最常見的就是通過addEventListener
來給目標元素添加事件偵聽。愛掏網 - it200.com比如:
myButton.addEventListener('click', function(){
alert('Hello, World!')
}, false)
HTMl屬性
我們可以在HTML元素中添加事件:
DOM元素屬性
我們也可以直接給一個DOM元素屬性添加相應的事件:
myButton.onclick = function(e){alert('Hello, World!')}
通常情況下,我們都習慣于使用addEventListener
來給目標元素(DOM元素)添加事件:
targetElement.addEventListener(eventName, eventHandler, false)
簡單介紹一下其組成部分:
-
targetElement
:要偵聽事件的元素或對象。愛掏網 - it200.com通常是一個DOM元素,也可以是document
、window
或任何專門用于觸發事件的對象 -
eventName
:事件名稱,在JavaScript中有關于事件的名稱列表可以點擊這里查閱 -
eventHandler
:事件處理程序,就是程序要做的事情(比如用戶點擊了按鈕,會發生什么事情?) - 事件冒泡或捕獲:這是最后一個參數,在JavaScript中指的是事件冒泡或捕獲
放到一起之后,他可能像下面這樣:
btnEle.addEventListener('click',showMessage('大漠'), false)
const showMessage = (name) => {
alert(`Hello, ${name}~`)
}
事件捕獲或冒泡
在JavaScript事件中還有一個很重要的概念,也比前面有關于事件的基礎知識更為復雜,那就是事件捕獲和事件冒泡。愛掏網 - it200.com為了更好的幫助我們理解事件中有關于這兩方面的概念,使用一個簡單的示例來向大家闡述。愛掏網 - it200.com
如果我們用DOM樹來描述上面的HTML結構的話,大致像下圖這樣:
假設用戶點擊了buttonOne
按鈕,即觸發了一個click
事件。愛掏網 - it200.com很多同學都會認為click
事件是從目標元素buttonOne
開始觸發,事實上并非如此,click
事件從文檔的根開始(即window
)。愛掏網 - it200.com如果用圖來描述的話,如下;
click
事件從文檔根(window
)開始,然后按照DOM樹的路徑一級一級往下尋找,直到觸發click
事件的butttOne
元素(也稱為事件目標)停止:
正如上圖所示,事件所經過的路徑是直的,它會通知該路徑上的每個元素。愛掏網 - it200.com如果該路徑上有與當前事件匹配的元素,那么就會調用對應的事件處理程序。愛掏網 - it200.com一旦事件達到目標,它就不會停止。愛掏網 - it200.com不同的是,事件會往上移。愛掏網 - it200.com事件路徑上的每個元素都會得到其存在的通知。愛掏網 - it200.com出現的任何事件處理程序也將被調用。愛掏網 - it200.com
需要注意的是,事件在哪個位置啟動并不重要,因為事件總是從文檔的根開始,向下直接到達目標,然后返回根。愛掏網 - it200.com在這樣的一個過程中,從根開始向下尋找事件目標的過程被稱為事件捕獲階段:
反過來,事件從目標元素向文檔根元素的過程被稱為事件冒泡階段:
也就是說,當一個事件被觸發時,會得到兩次通知。愛掏網 - it200.com每次監聽事件時,我們都會選擇要監聽哪個階段的事件。愛掏網 - it200.com這是一個細節,我們可以給addEventListener
指定true
或false
來進行設置:
-
true
:表示在捕獲階段偵聽事件 -
false
:表示在冒泡階段偵聽事件
有的時候我們需要結束事件的生命周期。愛掏網 - it200.com只需要在事件對象上使用stopPropagation
方法即可:
const handleClick = (e) => {
e.stopPropagation()
}
上面這些是JavaScript中事件的基礎知識,如果你想了解更多有關于JavaScript事件相關的知識,可以閱讀下面這些教程:
- DOM事件簡介
- DOM事件的傳播
- DOM事件模型
- 事件綁定的姿勢
- UI Events
- Javascript Events Tutorial with Complete List of Events
- An Introduction To DOM Events
- Understanding Events in JavaScript
- Browser Events and Event Listeners
- Introduction to Events
- JavaScript Event Loop Explained
- Understanding Javascript Function Executions — Call Stack, Event Loop , Tasks & more
- The JavaScript Event Loop
- JavaScript 運行機制詳解:再談Event Loop
- Faster async functions and promises
- JavaScript. Event Loop and Promises
基于我們現有的JavaScript經驗,你可能已經非常習慣使用事件。愛掏網 - it200.com但是,在React中處理事件的方式和JavaScript有所不同。愛掏網 - it200.comReact沒有直接針對DOM事件,而是將它們包裝在自己的事件包裝器中。愛掏網 - it200.com在接下來的小節中,我將和大家一起探討和學習React中事件相關的知識點。愛掏網 - it200.com
創建事件
為了更好的和大家聊React中的事件,我們從一個簡單的示例開始。愛掏網 - it200.com該示例創建一個包含input
和button
的表單控件。愛掏網 - it200.cominput
可以輸出你想要的文本內容,當input
輸入一個值時,將觸發一個事件(一般是onChange
)事件。愛掏網 - it200.com另外,用戶點擊按鈕時,也會觸發一個事件(一般是onClick
)事件,該事件會調用一個函數,該函數會將文本框的內容(文本)反轉。愛掏網 - it200.com
該示例大致是這樣工作的:
- 一個
input
,可以讓用戶輸入想要的內容 - 當用戶在
input
中輸入值時,將會觸發onChange
事件,它會調用一個handleChange()
函數,該函數用于設置input
的新狀態 - 當用戶點擊“點擊我”按鈕時(
button
),會觸發另一個事件,該事件會調用handleReverse()
函數,將輸入框的文本反轉
該示例的代碼大致如下:
const App = () => {
const [inputVal, setInputVal] = React.useState('')
const [reversedText, setReversedText] = React.useState('')
const handleChange = e => setInputVal(e.currentTarget.value)
const handleClick = e => {
e.preventDefault()
setReversedText(inputVal.split("").reverse().join(""))
}
return (
{reversedText}
)
}
上面示例中是React創建事件方式之一。愛掏網 - it200.com如果你是使用類來創建的組件,那么組件中的創建事件方法可以像下面這樣:
class MyComponent extends React.Component {
handleClick = () => {
// ...
}
render() {
return
}
}
如果使用React Hooks來創建組件的話,除了上例中useState()
方法外,我們還可以使用useRef()
方法:
// React Hooks中使用useState()創建事件
class MyComponent = () => {
const handleClick = e => useState()
return
}
// React Hooks中使用useRef()創建事件
class MyComponent = () => {
const handleChange = e => useRef()
return
支付4.99元