1. 程式人生 > >React 事件和 Dom 事件

React 事件和 Dom 事件

注意: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 上面的方法。