注意:Chrome 中列印的物件展開的時候顯示的是當前物件的值,可能已經不是列印的時候的值了,所以需要通過在列印的地方打斷點的形式來檢視準確的值。或者直接通過打斷點檢視。
React 事件和 dom 事件
兩者很像,只是有一些語法上的不一樣。
- 事件名 jsx 中採用駝峰命名。
- 引數是一個事件處理函式
原生的 dom 事件
click 事件和 href 的優先順序:
click >
>
>
href
第一種:Dom 元素中直接繫結
- 直接在 html 中寫為字串
如果在後面寫 return false
可以阻止預設事件。注意只能是字串形式的 js 程式碼,方法呼叫不行。
<
span onclick="console.log('我被點選了!!!')">
Click me<
/span>
複製程式碼
- 將 js 程式碼放到 js 函式中
<
span onclick="handle()">
Click me<
/span>
function handle() {
console.log('我被點選了!!!);
}複製程式碼
第二種:在 JavaScript 程式碼中繫結
- DOM0 的寫法:直接在 dom 物件上註冊事件名稱
此時返回 false 可以阻止預設事件。
elementObject.onclick = function(){
// 事件處理程式碼
}複製程式碼
-
Dom 2 的寫法:
- DOM2 支援同一dom元素註冊多個同種事件。
- DOM2 新增了捕獲和冒泡的概念。
- DOM2 事件通過 addEventListener 和 removeEventListener 管理
ele.addEventListener(‘click’, handle, false);
複製程式碼
事件物件
無論在DOM0還是DOM2還是DOM3中都會在事件函式中傳入事件物件;
常用屬性:
currentTarget : 當前時間程式正在處理的元素, 和this一樣的;
target || srcElement: 事件的目標 view : 與元素關聯的window, 我們可能跨iframe; eventPhase: 如果值為1表示處於捕獲階段, 值為2表示處於目標階段,值為三表示在冒泡階段 preventDefault() 取消預設事件; stopPropagation() 取消冒泡或者捕獲; stopImmediatePropagation 阻止繫結在事件觸發元素其他同類事件的callback的執行 trusted: 為ture是瀏覽器生成的,為false是開發人員建立的(DOM3)複製程式碼
注意誤區:
- 在同一個物件上註冊事件,並不一定按照註冊順序執行
事件目的地節點既繫結了冒泡事件也繫結了捕獲事件,如果是同一型別則按照程式碼執行順序執行
- event.stopPropagation();
就是阻止事件的冒泡?
除了阻止事件的冒泡,還阻止事件的繼續捕獲,簡而言之就是阻止事件的進一步傳播。
React 事件
介面和原來的 dom 事件一致。繫結處理函式分兩種情況:
包裝了瀏覽器的原生的事件,並且是跨瀏覽器的。
- 不傳引數
<
div className="box1" onClick={this.handleClickOne
}>
複製程式碼
- 傳遞引數有兩種寫法:
1. 箭頭函式:<
div className="box2" onClick={e =>
this.handleClickTwo(e)
} 2. bind 方法:<
div className="box2" onClick={this.handleClickTwo.bind(this, e, others)
}複製程式碼
事件重用
Event Pooling:事件池
react 中的事件會被重用,每一次事件對應的回撥函式執行後事件上的所有屬性都會失效。
比如通過 setTimeout 非同步方式訪問事件會報錯。
此時的解決方法是呼叫 persist() 方法移出事件池從而保留事件物件。
事件處理函式的執行時機
事件處理函式都是在冒泡階段執行,如果要讓事件處理函式在捕獲階段執行,事件名後面加 Capture
就行。
onClick ==>
onClickCapture 複製程式碼
React 中阻止事件冒泡的三種方式
合成事件中的 currentTarget 指向當前 dom 元素,但是 nativeEvent 的 currentTarget 指向 document
- 阻止合成事件間的冒泡,用e.stopPropagation();
- 阻止合成事件與最外層 document 上的事件間的冒泡
nativeEvent 的 currentTarget 指向 document e.nativeEvent.stopImmediatePropagation();
複製程式碼
- 阻止合成事件與 除最外層document上的原生事件 上的冒泡,通過判斷 e.target 來避免
document.body.addEventListener('click',e=>
{
// 通過e.target判斷阻止冒泡 if(e.target&
&
e.target.matches('a')){
return;
} console.log('body');
})複製程式碼
自定義 dom 事件
使用到的事件物件有 Event
和 CustomEvent
自定義事件和觸發事件:
// 通過 Event 建立新的事件 const event = new Event('newEvent');
box1.addEventListener('newEvent', function() {
console.log('newEvent 事件被觸發了!!!!')
});
setTimeout(function() {
// 通過呼叫元素的 dispatchEvent 方法在該元素上面觸發該事件 box1.dispatchEvent(event);
}, 2000);
複製程式碼
自定義事件的時候,為事件物件新增資料:
const customEvent = new CustomEvent('customEvent', {
'data': '2121212'
});
box1.addEventListener('customEvent', function(e) {
console.log('customEvent 事件被觸發了!!!!', e, customEvent)
});
setTimeout(function() {
box1.dispatchEvent(customEvent);
}, 2000);
複製程式碼
程式碼控制觸發內建事件
box1.addEventListener('click', function(e) {
console.log('程式碼控制觸發內建事件', e)
});
setTimeout(function() {
const click = new MouseEvent('click') box1.dispatchEvent(click)
}, 2000)複製程式碼
其中 click
事件還可以通過 HTMLElement
物件上面的 的 click()
方法模擬。
其中 querySelector 和 querySelectorAll
是 Element
上面的方法。