事件

这里的事件,指的是 React 内部封装 DOM 组件中的事件,如 onClick, onFocus等,而非我们自己通过 props 传递的属性,并在子组件中手动触发的事件

实例

import React, { Component } from 'react';

class TodoList extends Component {

render() {

return (

);

}

handelClick () {

console.log(1)

console.log(this)

}

// 箭头函数

handelClick2 = () => {

console.log(2)

console.log(this)

}

// 箭头函数

handelClick3 = () => {

console.log(3)

console.log(this)

}

}

export default TodoList;

react事件声明

react事件采用驼峰式命名react事件接收一个函数声明,不是函数调用的形式

//原生

//react

绑定事件

采用on+事件名的方式来绑定一个事件.

注意,这里和原生的事件是有区别的: 原生的事件全是小写onclick , React里的事件是驼峰 onClick ,React的事件并不是原生事件,而是合成事件。

事件handler的写法

直接在render里写行内的箭头函数(不推荐)在组件内使用箭头函数定义一个方法(推荐)直接在组件内定义一个非箭头函数的方法,然后在render里直接使用 onClick={this.handleClick.bind(this)} (不推荐)直接在组件内定义一个非箭头函数的方法,然后在constructor里bind(this)(推荐)

Event 对象

和普通浏览器一样,事件handler会被自动传入一个 event 对象,这个对象和普通的浏览器 event 对象所包含的方法和属性都基本一致。不同的是React中的 event 对象并不是浏览器提供的,而是它自己内部所构建的。它同样具有 event.stopPropagation 、 event.preventDefault 这种常用的方法.

this问题

实例

import React, { Component } from 'react';

class TodoList extends Component {

render() {

return (

{/* :如果逻辑过不多,此写法推荐 */}

{/* 可以直接访问this,无需手动绑定 */}

{/* :此写法不推荐 */}

{/* 不可以直接访问this,需手动绑定 -- .bind(this)*/}

{/* :此写法推荐 */}

{/* 可以直接访问this,无需手动绑定,handelClick2是箭头函数,可以绑定外部this :此写法推荐 */}

{/* :此写法比较推荐,传参数很方便 */}

{/* 可以直接访问this,无需手动绑定,onClick调用的是箭头函数,可以绑定外部this */}

);

}

handelClick () {

console.log(1)

console.log(this)

}

// 箭头函数

handelClick2 = (evt) => {

console.log(2)

console.log(this)

// 打印 Event 对象

console.log(evt)

}

// 箭头函数

handelClick3 = (evt) => {

console.log(3)

// 打印 Event 对象

console.log(evt)

}

}

export default TodoList;

为什么使用bind绑定this

class组件的事件绑定this问题

1. class的方法默认不会绑定 this,如果没有绑定 this.handleClick的this 并把它传入了 onClick,当你调用这个函数的时候 this 的值为 undefined。

class A extends React.Component{

constructor(props){

super(props)

}

handleClick(){

//class的方法默认不会绑定 `this`,this的指向根据调用的方式判断

//没有绑定调用的话this为undefined

this.setState({a:1})

}

render(){

return (

)

}

}

this问题的解决方式有三种

(1)在constructor里使用bind为方法绑定this

class A extends React.Component{

constructor(props){

super(props)

this.handleClick= this.handleClick.bind(this); // 注意此处

}

handleClick(){

this.setState({a:1})

}

}

(2)在元素上绑定事件时使用箭头函数

class A extends React.Component{

constructor(props){

super(props)

}

handleClick(){

//class的方法默认不会绑定 `this`,this的指向根据调用的方式判断

//没有绑定调用的话this为undefined

this.setState({a:1})

}

render(){

//render里的this指向自身

return (

this.handleClick() }>

)

}

}

(3)使用箭头函数声明方法

class A extends React.Component{

constructor(props){

super(props)

}

handleClick=()=>{

//箭头函数的this由父作用域的this判断

this.setState({a:1})

}

render(){

//render里的this指向自身

return (

)

}

}

react事件传递参数

1.要在绑定事件的位置给事件传参有两种方式,

(1)通过bind,使用bind会隐式传入事件对象e,作为函数的最后一个参数。

(2)通过箭头函数,使用箭头函数需要主动传入事件对象e 。

事件说明

React 根据 W3C 规范定义了合成事件 (SyntheticEvent),我们就无需担心跨浏览器的兼容性问题 React 出于性能与事件管理方面的考量,在之前的 React 版本中 (v17 之前)

会将在 JSX 中注册的事件收集到 document 上 (即通过事件委托,在 document 上注册事件,等触发事件时,则按虚拟 DOM 树的结构进行事件触发机制去分发事件);几乎所有的事件处理,均在 document 的事件中处理

比如 onFocus 等事件不会冒泡的事件,就不做委托,直接在元素上监听一些 document 上没有的事件,也直接在元素上监听 (如:audio、video标签的事件等) 在 document 中的事件处理,会根据虚拟 DOM 树的结构完成事件函数的调用,默认是冒泡机制 (事件捕获要通过类似 onClickCapture 的方式注册)React 的事件参数,并非真实的事件参数,而是 React 合成的一个对象 (SyntheticEvent)

通过调用 e.stopPropagation() 阻止事件冒泡 (仅阻止 React 事件)通过 e.nativeEvent 可以得到真实的 DOM 事件对象 (不过很少会用到)为了提高效率,React 使用事件对象池来处理事件对象 (即事件对象会重用) 在 React 17 之后,事件委托的节点就转移到了渲染的根节点上,而且也帮我们解决了此类关于事件冒泡的问题 (本文测试用例则说明,对于使用 ReactDOM.createPortal 创建的组件,表现上略有差异)

注意点

若给真实 DOM 注册事件,并阻止冒泡,则很有可能导致 React (JSX) 中注册的相关事件无法触发若给真实 DOM 注册事件,它会先于 React 事件执行 (即通过 onClick 和 dom.addEventListener 绑定的事件,真实 DOM 事件会先执行;因为这个元素被点击时,真实 DOM 事件会很快找到,而 React 绑定的事件则需要去找到事件委托的元素,再去调用当前点击元素绑定的事件函数)过 React 事件阻止事件冒泡,无法阻止真实 DOM 事件的冒泡可以使用 e.nativeEvent.stopImmediatePropagation() 去阻止 document 上剩余的事件处理程序的运行 (当我们在使用某些第三方库,在这个库有可能使用了一些事件处理,也对 document 绑定过点击事件,如: document.addEventListener("click", handler))在事件处理程序中,不要异步使用事件对象 e;如果一定有异步使用的需求,则需要调用e.persist()函数持久化保存此事件对象 (代价自然是损耗效率的)

React 事件总结

绑定事件处理函数

1.1 鼠标类

onContextMenuonClickonDoubleClickonMouseDownonMouseUponMouseEnteronMouseLeaveonMouseMoveonMouseOutonMouseOver

1.2 拖拽事件:

onDroponDragonDragStartonDragEndonDragEnteronDragLeaveonDragOveronDragExit

1.3 触摸

触摸只会在移动设备上产生

onTouchStartonTouchEndonTouchMoveonTouchCancel

1.4 键盘

onKeyPress是onKeyDown和onKeyUp的组合

onKeyPressonKeyDownonKeyUp

剪切类

对应的是我们常常使用的复制、剪切和粘贴

onCopyonCutonPaste

表单类

onChangeonInputonSubmitonChange可以用在输入框、单选框、下拉列表里,每当内容发生变化时我们都能获得通知。

onInput使用在文字输入。

onSubmit是用在整个表单的输入提交,常用在禁止表单的默认操作。

1.7 焦点事件

onFocusonBlur

1.8 UI元素类

onScroll

滚动事件触发的时候会触发onScroll事件

1.9 滚动

onWheel

鼠标滚轮触发的事件,监听滚动幅度,滚动方位

1.10 组成事件

onCompositionEndonCompositionStartonCompositionUpdate

1.11 图片类

onLoadonError

1.12 多媒体类

onAbortonCanPlayonCanPlayThroughonDurationChangeonEmptiedonEncryptedonEndedonErroronLoadedDataonLoadedMetadataonLoadStartonPauseonPlayonPlayingonProgressonRateChangeonSeekedonSeekingonStalledonSuspendonTimeUpdateonVolumeChangeonWaiting

事件池

虚拟事件对象已经被合并。这意味着虚拟事件对象将被重新使用,而该事件回调被调用之后所有的属性将无效。这是出于性能的考虑。因此,您不能以异步的方式访问事件。

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}); // 您依然可以导出事件属性

}

如果您想以一个异步的方式来访问事件属性,您应该对事件调用event.persist()。这将从事件池中取出合成的事件,并允许该事件的引用,使用户的代码被保留。

事件对象

事件处理器将会传入SyntheticEvent的实例,一个对浏览器本地事件的跨浏览器封装。它有和浏览器本地事件有相同的属性和方法,包括stopPropagation()和preventDefault(),但是没有浏览器兼容问题。

如果因为一些因素,需要底层的浏览器事件对象,只要使用nativeEvent属性就可以获取到它了。

对于 v0.14,在事件处理函数中返回 false 将不会阻止事件冒泡。取而代之的是在合适的应用场景下,手动调用e.stopPropagation()或者e.preventDefault()。

handleChange:function(e){

console.log(e.target.value);

}

其中target是 事件对象e 是事件对象的属性

通用属性

(以下内容括号内为类型)

bubbles (boolean) 表示事件是否冒泡cancelable(boolean) 表示事件是否可以取消currentTarget(DOMEventTarget) 与Target类似,由于事件可以冒泡,所以两者表示的内容是不同的defaultPrevented(boolean) 表示事件是否禁止了默认行为eventPhase(number) 表示事件所处的阶段isTrusted(boolean) 表示事件是否可信。所谓的可信事件表示的是用户操作的事件,不可信事件就是通过JS代码来触发的事件。nativeEvent(DOMEvent)preventDefault() (void) 对应的defaultPrevented,表示的是禁止默认行为stopPropagaTion() (void) 对应的是bubbles,表示的是shtarget(DOMEventTarget)timeStamp(number) 时间戳,也就是事件触发的事件type(string) 事件的类型

不同事件对象的特有属性

剪切事件

clipboardData(DOMDataTransfer)表示拿到的数据

键盘事件

ctrlKey(boolean) 表示是否按下ctrl键altKey(boolean) 表示是否按下alt键shiftKey(boolean) 表示是否按下shiftmetaKey(boolean) 表示的是win系统下的win键,mac系统下对应的command键getModifierState(key) (function) 表示是否按下辅助按键(辅助按键就是雷士ctrl、shift等辅助按键)可以传入按键编码来判断是否按下charCode(Number) 表示的是按键的字符编码,可以通过编码来判断按下的是什么键key(string) 字符串,按下的键keyCode(Number) 表示那些不是字符编码的按键which(Number) 表示经过通用化得charCode和keyCodelocale(String) 表示本地化得一些字符串location(number) 表示位置repeat(boolean) 表示按键是否重复

焦点事件

relatedTarget(DOMEventTarget) 相关焦点对象

鼠标事件

ctrlKey(boolean)altKey(boolean)shiftKey(boolean)metaKey(boolean)getModifierState(key) (function)button(Number)buttons(Number)clientX(Number) 原点为浏览器左上角clinetY(Number) 原点为浏览器左上角pageX(Number) 原点为HTML页面的左上角pageY(Number) 原点为HTML页面的左上角screenX(Number) 原点为显示器的左上角screenY(Number) 原点为显示器的左上角relatedTarget(DOMEventTarget)

触摸事件

为了使触摸事件生效,在渲染所有组件之前调用 React.initializeTouchEvents(true)。

ctrlKey(boolean)altKey(boolean)shiftKey(boolean)metaKey(boolean)getModifierState(key)changedTouches(DOMTouchList) 判断手势操作targetTouches(DOMTouchList) 判断手势操作touches(DOMTouchList) 判断手势操作

UI元素事件

detail(Number) 滚动的距离view(DOMAbstractView) 界面,视窗

鼠标滚动

deltaMode(Number) 可以理解为移动的单位deltaX(Number) X轴移动的相对距离固定值deltaY(Number) Y轴移动的相对距离固定值deltaZ(Number) Z轴移动的相对距离固定值

实例

滚动事件对象

var HelloDada = React.creatClass({

getInitialState:function(){

return {

backgroundColor:'#FFFFFF'

}

},

handleWheel:function(e){

var newColor = (parseInt(this.state.backgroundColor.substr(1),16)+e.deltaY*997).tiString(16);

this.setState({

backgroundColor:newColor

})

},

render:function(){

return

// 注意这里 onWheel

Dada Shuaige

}

});

ReactDOM.render(,document.body)

键盘事件对象

var Dada =React.creatClass{

getInitialState:function(){

return{

password:''

}

},

handleKeyPress:function(e){

this.setState({

paddword:this.state.password+e.which

});

},

handleChange:function(e){

e.target.value='';

},

render:function(){

return

// 注意这里 onKeyPress

'display':this.state.password.indexOf('495051') >=0?'block':'none'

}}>Dada handsomeboy

}

};

ReactDOM.render(,document.body)

事件与状态关联

状态不仅仅实现了组件内部结果的清晰对应,还实现了组件与用户之间的交互,使用户与组件的行为紧紧结合起来

handleChange:function(e){

this.setState({Dada:e.target.value});

}

this.setState设置状态

实例

var Dada =React.creatClass({

getInitialState:function(){

return{

x:0,

y:0

}

},

handleMouseMove:function(e){

this.setState({

x:e.clientX,

y:e.clientY

});

},

render:function(){

return

width:'200px',

height:'200px',

backgroundColor:'#999'

}}>

{this.state.x+'.'+this.state.y}

}

});

ReactDOM.render(,document.body)

React绑定事件和原生绑定事件的区别

react事件和原生事件的区别是:

react中的事件是绑定到document上面 , React并不会真正的绑定事件到每一个具体《》的元素上,而是采用事件代理的模式:而原生的事件是绑定到dom上面。

相对绑定的地方来说,dom上的事件要优先于document上的事件执行,react的事件对象是合成。

参考链接:

https://blog.csdn.net/qq_40340943/article/details/107309779https://www.bbsmax.com/A/Gkz1PBOgdR/

好文链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。