React 事件和 Dom 事件

liushanga發表於2019-01-12

注意:Chrome 中列印的物件展開的時候顯示的是當前物件的值,可能已經不是列印的時候的值了,所以需要通過在列印的地方打斷點的形式來檢視準確的值。或者直接通過打斷點檢視。

React 事件和 dom 事件

兩者很像,只是有一些語法上的不一樣。

  1. 事件名 jsx 中採用駝峰命名。
  2. 引數是一個事件處理函式

原生的 dom 事件

click 事件和 href 的優先順序:

click >
>
>
href

第一種:Dom 元素中直接繫結

  1. 直接在 html 中寫為字串

如果在後面寫 return false 可以阻止預設事件。注意只能是字串形式的 js 程式碼,方法呼叫不行。

<
span onclick="console.log('我被點選了!!!')">
Click me<
/span>
複製程式碼
  1. 將 js 程式碼放到 js 函式中
    <
span onclick="handle()">
Click me<
/span>
function handle() {
console.log('我被點選了!!!);

}
複製程式碼

第二種:在 JavaScript 程式碼中繫結

  1. DOM0 的寫法:直接在 dom 物件上註冊事件名稱

此時返回 false 可以阻止預設事件。

    elementObject.onclick = function(){ 
// 事件處理程式碼
}複製程式碼
  1. Dom 2 的寫法:

    1. DOM2 支援同一dom元素註冊多個同種事件。
    2. DOM2 新增了捕獲和冒泡的概念。
    3. 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)複製程式碼

注意誤區:

  1. 在同一個物件上註冊事件,並不一定按照註冊順序執行

事件目的地節點既繫結了冒泡事件也繫結了捕獲事件,如果是同一型別則按照程式碼執行順序執行

  1. event.stopPropagation();
    就是阻止事件的冒泡?

除了阻止事件的冒泡,還阻止事件的繼續捕獲,簡而言之就是阻止事件的進一步傳播。

React 事件

介面和原來的 dom 事件一致。繫結處理函式分兩種情況:

包裝了瀏覽器的原生的事件,並且是跨瀏覽器的。

  1. 不傳引數
    <
div className="box1" onClick={this.handleClickOne
}>
複製程式碼
  1. 傳遞引數有兩種寫法:
    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 元素,但是 nativeEventcurrentTarget 指向 document

  1. 阻止合成事件間的冒泡,用e.stopPropagation();
  2. 阻止合成事件與最外層 document 上的事件間的冒泡
    nativeEvent 的 currentTarget 指向 document    e.nativeEvent.stopImmediatePropagation();
複製程式碼
  1. 阻止合成事件與 除最外層document上的原生事件 上的冒泡,通過判斷 e.target 來避免
    document.body.addEventListener('click',e=>
{
// 通過e.target判斷阻止冒泡 if(e.target&
&
e.target.matches('a')){
return;

} console.log('body');

})複製程式碼

自定義 dom 事件

使用到的事件物件有 EventCustomEvent

自定義事件和觸發事件:

    // 通過 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 和 querySelectorAllElement 上面的方法。

來源:https://juejin.im/post/5c39a0c86fb9a049c84faee6

相關文章