[譯]合成事件對象

前言

本文爲意譯,翻譯過程當中摻雜本人的理解,若有誤導,請放棄繼續閱讀。html

原文地址:SyntheticEventreact

簡介

這是一份關於SyntheticEvent wrapper的文檔。SyntheticEvent wrapper是什麼?能夠這麼說,react的合成事件系統是由(React’s Event SystemSyn)一個個的SyntheticEvent wrapper組成的。而SyntheticEvent wrapper有時候又簡稱爲SyntheticEvent,中文翻譯爲合成事件對象。要想了解更多?請參考如何應用合成事件對象瀏覽器

概覽

在run time中,你的react事件處理器將會被傳入一個SyntheticEvent實例對象做爲實參。SyntheticEvent是一個對瀏覽器原生事件對象(native event)進行跨瀏覽器封裝的wrapper。它與瀏覽器的原生事件對象有着一樣的接口,好比,它也包括了stopPropagation()preventDefault()這兩個方法。它的目的是使得事件對象在不一樣的瀏覽器上都表現一致,提高開發者的開發體驗。bash

若是你發現,你由於某種緣由須要使用到瀏覽器原生的事件對象,那麼你能夠簡單地經過讀取SyntheticEvent對象的nativeEvent屬性來訪問它。像下面那樣:app

class SomeComponent extends React.Component {
    handleClick=(e)=> {
        const nativeEvent = e.nativeEvent;
        console.log(nativeEvent)
    }
    render(){
        return <button onClick={this.handleClick}>click me</button>
    }
}
複製代碼

每個SyntheticEvent實例對象都包含了如下屬性:dom

boolean bubbles
boolean cancelable
DOMEventTarget currentTarget
boolean defaultPrevented
number eventPhase
boolean isTrusted
DOMEvent nativeEvent
void preventDefault()
boolean isDefaultPrevented()
void stopPropagation()
boolean isPropagationStopped()
DOMEventTarget target
number timeStamp
string type
複製代碼

注意: 自v0.14版本起,在一個事件處理器中返回false,已是沒法阻止事件的傳播了。你須要手動地調用e.stopPropagation()或者e.preventDefault()方法才行。異步

事件對象的共享機制(Event Pooling)

pooling,在這裏我意譯爲「共享」。由於react的事件系統中,1) 同一個事件類型下的全部事件處理器都是共享同一個SyntheticEvent實例對象; 2) 在不手動持久化的前提下,同一個事件處理器在不一樣的調用次序中都是共享同一個SyntheticEvent實例對象。基於上述的事實,我以爲把它翻譯爲「共享」較爲貼切。這個翻譯參考了劍橋英語詞典對該單詞的釋義。也有人把它翻譯爲「池化」,我不知道哪一個撲街帶頭這麼幹的,詳見知乎吐槽性能

SyntheticEvent實例對象是共享的。這意味着SyntheticEvent實例對象是會被反覆使用的,而且會在事件處理器被調用以後回收。所謂的回收,就是對該對象的全部屬性值置爲空值(will be nullified ),以便於在下一輪事件傳播中使用。之因此採用這種機制,是爲了提高react的運行性能。因此說,你不能使用異步的方式來訪問SyntheticEvent實例對象的屬性值動畫

function onClick(event) {
  console.log(event); // => nullified object.
  console.log(event.type); // => "click"
  const eventType = event.type; // => "click"

  setTimeout(function() {
    console.log(event.type); // => null
    console.log(eventType); // => "click"
  }, 0);

  // will not work. this.state.clickEvent will only contain null values.
  this.setState({clickEvent: event});

  // You can still export event properties.
  this.setState({eventType: event.type});
}
複製代碼

上面的setTimeout雖然是寫在的事件處理器裏面,可是它終究是異步代碼。上面代碼的實際執行流程是:同步代碼 --> SyntheticEvent對象(屬性)置空值 --> 異步代碼。由於異步代碼老是在置空值的後面才執行,因此,咱們訪問到的老是空值。ui

注意: 若是你想在異步代碼裏面訪問SyntheticEvent對象的屬性。那麼你應該手動調用event.persist(),你一旦這麼作了,react就會把這個SyntheticEvent對象從共享池中去掉。這樣子,用戶就能夠放心地去訪問這個被從共享池中解放出來的SyntheticEvent對象了。

支持的事件

React對合成事件對象作了統一化,使得在不一樣的瀏覽器上對象所支持的屬性都是一致的。

若是你想把一個事件處理器綁定在捕獲階段(capture phase),那麼你就須要在該事件名後面追加一個Capture:例如,若是你想把點擊事件的事件處理器綁定在事件的捕獲階段,那麼在事件註冊時,你應該寫onClickCapture,而不是onClick

如下都是一些在事件冒泡階段觸發(bubbling phase)的事件。

  • Clipboard Events
  • Composition Events
  • Keyboard Events
  • Focus Events
  • Form Events
  • Mouse Events
  • Pointer Events
  • Touch Events
  • UI Events
  • Wheel Events
  • Media Events
  • Animation Events
  • Transiton Events
  • Other Events

參考指南

Clipboard Events

事件名:

onCopy
onCut
onPaste
複製代碼

屬性:

DOMDataTransfer clipboardData
複製代碼

composition Events

The DOM CompositionEvent represents events that occur due to the user indirectly entering text. --- MDN

事件名:

onCompositionStart
onCompositionUpdate
onCompositionEnd
複製代碼

屬性:

string data
複製代碼

keyboard Events

事件名:

onKeyDown
onKeyPress
onKeyUp
複製代碼

屬性:

boolean altKey
number charCode
boolean ctrlKey
boolean getModifierState(key)
string key 
number keyCode
string locale
number location
boolean metaKey
boolean repeat
boolean shiftKey
number which
複製代碼

key的屬性值的取值爲任意DOM Level 3 Events spec所指定的值。

Focus Events

事件名:

onFocus
onBlue
複製代碼

屬性:

DOMEventTarget relatedTarget
複製代碼

注意:不一樣於瀏覽器原生的focus事件只會在form元素上觸發,這個合成的focus事件會在全部的React DOM元素上觸發

Form Events

事件名:

onChange
onInput
onInvalid
onSubmit
複製代碼

更多關於onChange事件的信息,詳見Forms

Mouse Events

事件名:

onClick
onDoubleClick
onDrag
onDragEnd
onDragEnter
onDragExit
onDragLeave
onDragOver
onDragStart
onDrop
onMouseDown
onMouseEnter
onMouseLeave
onMouseMove
onMouseOut
onMouseOver
onMouseUp
onContextMenu
onInvalid
onSubmit
複製代碼

The onMouseEnter and onMouseLeave events propagate from the element being left to the one being entered instead of ordinary bubbling and do not have a capture phase.(這段話意思難懂)。

屬性名:

boolean altKey
number button
number buttons
number clientX
number clientY
boolean ctrlKey
boolean getModifierState(key)
boolean metaKey
number pageX
number pageY
DOMEventTarget relatedTarget
number screenX
number screenY
boolean shiftKey
複製代碼

Pointer Events

Pointer應該是在HTML5增長的事件,具體見MDN

事件名:

onPointerDown
onPointerMove
onPointerUp
onPointerCancel
onGotPointerCapture
onLostPointerCapture
onPointerEnter
onPointerLeave
onPointerOver
onPointerOut
複製代碼

The onPointerEnter and onPointerLeave events propagate from the element being left to the one being entered instead of ordinary bubbling and do not have a capture phase.(again)

屬性:

如W3C規範所規定的那樣,pointer事件繼承自Mouse Events,而且多出瞭如下如下屬性:

number pointerId
number width
number height
number pressure
number tangentialPressure
number tiltX
number tiltY
number twist
string pointerType
boolean isPrimary
複製代碼

在跨瀏覽器支持方面的一個提示:

Pointer events are not yet supported in every browser (at the time of writing this article, supported browsers include: Chrome, Firefox, Edge, and Internet Explorer). React之因此故意不對其餘不支持的瀏覽器添加相應的polyfill,那是由於一個符合標準的(standard-conform)的polyfill會大大地增長react-dom的文件大小。

若是你的應用中須要用到pointer事件,那麼咱們會建議你單獨引入一個第三方的pointer事件的polyfill。

selection Events

事件名:

onSelect
複製代碼

Touch Events

事件名:

onTouchStart
onTouchMove
onTouchCancel
onTouchEnd
複製代碼

屬性:

boolean altKey
DOMTouchList changedTouches
boolean ctrlKey
boolean getModifierState(key)
boolean metaKey
boolean shiftKey
DOMTouchList targetTouches
DOMTouchList touches
複製代碼

UI Events

事件名:

onScroll
複製代碼

屬性:

number detail
DOMAbstractView view
複製代碼

Wheel Events

事件名:

onWheel
複製代碼

屬性:

number deltaMode
number deltaX
number deltaY
number deltaZ
複製代碼

Media Events

事件名:

onAbort
onCanPlay
onCanPlayThrough
onDurationChange // 播放時長的改變事件
onEmptied // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/emptied_event
onEncrypted // 多媒體加密事件
onEnded
onError
onLoadedData
onLoadedMetadata
onLoadStart
onPause
onPlay
onPlaying
onProgress
onRateChange
onSeeked
onSeeking
onStalled // stalled的意思是「停滯不前的」
onSuspend
onTimeUpdate
onVolumeChange
onWaiting
複製代碼

Image Events

事件名:

onLoad
onError
複製代碼

Animation Events

事件名:

onAnimationStart
onAnimationEnd
onAnimationIteration // 在一次動畫迭代結束的時候觸發
複製代碼

屬性名:

string animationName
string pseudoElement
float elapsedTime
複製代碼

Transition Events

事件名:

onTransitionEnd
複製代碼

屬性名:

string propertyName
string pseudoElement
float elapsedTime
複製代碼

其餘事件

事件名:

onToggle
複製代碼
相關文章
相關標籤/搜索