React事件系統(tǒng)
事件處理程序通過
合成事件(SyntheticEvent)
的實例傳遞役电,SyntheticEvent
是瀏覽器原生事件跨瀏覽器的封裝
。SyntheticEvent 和瀏覽器原生事件一樣有 stopPropagation()冒签、preventDefault() 接口闯两,而且這些接口跨瀏覽器兼容。
- 原生事件
document.querySelector('xxx').addEventListener('click', () => {
console.log(event);
})
// 輸出1:windowEvent ====> chorme
// 輸出2: undefined ====> Firefox
可以看出event參數(shù)不加的話腥沽,有的瀏覽器會兼容逮走,像火狐就不兼容,因此需要在事件handler中寫
document.querySelector('xxx').addEventListener('click', event => {
event = event || window.event;
event.stopPropagation();
event.preventDefault();
})
如果不寫event而是在函數(shù)中傳了某種參數(shù)今阳,如果是chorme還好师溅,會給你補充一個window.event,某些不支持的瀏覽器就會把你的參數(shù)當(dāng)event了盾舌,當(dāng)然會報錯了;
- React的事件
- 0.12版本之前可以使用在event handler(onclick = xxx.bind(this))函數(shù)中使用
return false
來代替stopPropagation 和 preventDefault, 目前已經(jīng)被移除墓臭,請不要使用。 - 使用
合成事件(SyntheticEvent)
(類似jquery的$event)是對各種瀏覽器兼容的event相關(guān)封裝妖谴,目前支持以下屬性- boolean bubbles
- boolean cancelable
- DOMEventTarget currentTarget
- boolean defaultPrevented
- Number eventPhase
- boolean isTrusted
- DOMEvent nativeEvent
- void preventDefault()
- void stopPropagation()
- DOMEventTarget target
- Date timeStamp
- String type
- 默認(rèn)所有事件都在冒泡階段被觸發(fā)窿锉,如果想使用事件捕獲有兩種方法
- 使用原生addEventListener('click', handler, true)
第三個參數(shù)給true
- 使用onClickCapture = xxx.bind(this);
- 使用原生addEventListener('click', handler, true)
- 傳統(tǒng)開發(fā)方式在元素較多時建議使用
事件委托 / 事件代理
方式在父級進(jìn)行代理事件酌摇,但React獨特的事件處理系統(tǒng)會先把所有事件處理函數(shù)都收集到父級,再根據(jù)組件進(jìn)行派發(fā)嗡载,因此無需特意寫事件代理函數(shù)窑多,即使一個列表有一萬個組件元構(gòu)成,onClick函數(shù)也可以寫在組件元中洼滚。 - 事件池
event在React是一個虛擬對象埂息,在事件被收集后到父級元素中時,虛擬對象會被合并遥巴,在該事件處理的回調(diào)后屬性就沒用了千康,如果用setState這種異步方法調(diào)用的話就沒有用了。
function onClick(event) {
console.log(event); // =>無效的對象
console.log(event.type); // => "click"
var eventType = event.type; // => "click"
setTimeout(function() {
console.log(event.type); // => null
console.log(eventType); // => "click"
}, 0);
this.setState({clickEvent: event}); // 不起作用.this.state.clickEvent 將只包含空值.
this.setState({eventType: event.type}); // 您依然可以導(dǎo)出事件屬性
}
如果您想以一個異步的方式來訪問事件屬性铲掐,您應(yīng)該對事件調(diào)用event.persist()吧秕。這將從事件池中取出合成的事件,并允許該事件的引用迹炼,使用戶的代碼被保留砸彬。