目录
复习-原生js进行事件绑定
原生js具有三种事件绑定方式: 行内事件绑定、使用on关键字进行事件绑定、使用addEventListener方法进行事件绑定
行内事件绑定
语法
<标签 onxxx='执行代码'></标签>
- 当事件被触发时,就会执行引号间的代码
- 举例说明1
当点击该标签时就会在控制台打印-执行了<div onclick="console.log('执行了')">点击</div>
- 举例说明2
点击该标签时就会在控制台打印-执行了<div onclick="test1()">点击</div> <script> function test1(){ console.log('执行了') } </script>
原理
当触发事件时就会执行绑定的代码!!!若你绑定的是一段逻辑代码,触发事件直接执行逻辑代码; 若是方法的调用
,触发事件时是直接调用
该事件函数,this指向window。
通过on关键字进行事件绑定
语法
dom.onxxx = 函数
- 当事件被触发时,就会通过该dom元素调用绑定的方法
- 举例说明
<div id="test">点击</div> <script> function test(){ console.log('执行了') } document.getElementById('test').onclick = test </script>
原理
当事件被触发时,就会通过该dom元素调用绑定的方法,方法内部的this指向为 dom元素
通过addEventListener方法进行事件绑定
语法
dom.addEventListener(事件类型,方法名,bol)
- 当事件被触发时,就会通过该dom元素调用绑定的方法
- 举例说明
<div id="test">点击</div> <script> function test(){ console.log('执行了') } document.getElementById('test').addEventListener('click', test, false) </script>
原理
当事件被触发时,就会通过该dom元素调用绑定的方法,方法内部的this指向为 dom元素
react中进行事件绑定
在react中这三种方式均支持,但是为了减少dom操作,更推荐使用行内方式
进行事件绑定
语法
<标签 onXxx='方法名'></标签>
举例说明
<div id="test"></div>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
class Test extends React.Component{
render(){
return <h1 onClick={this.test}>点击</h1>
}
test(){
console.log('执行了')
}
}
ReactDOM.render(<Test/>,document.getElementById('test'))
</script>
与原生区别
- 事件名
- 原生为非驼峰命名(onxxx)
- react为驼峰命名(onXxx)
- 为什么react中事件绑定与原生js事件绑定不一致?
- react并不是使用的原生DOM事件,而是在原生DOM事件基础之上封装了一层(onXxx是基于onxxx封装的)
- 为了更好的兼容性
- 为了更加高效–通过事件委托方式处理的(委托给组件最外层的元素)
- react并不是使用的原生DOM事件,而是在原生DOM事件基础之上封装了一层(onXxx是基于onxxx封装的)
- 绑定的值
- 原生为逻辑代码/方法的调用
- react为 方法名
- 为什么react绑定的是函数而不是函数调用->实现原理不同
- 原生js是当事件被触发时 执行 对应的逻辑代码
当点击事件被触发时,执行引号间的代码-> 发现是函数调用-> 直接调用函数;<div onclick="test1()">点击</div> <script> function test1(){ console.log('执行了') } </script>
- react在调用render函数时会获取到vdom,若是发现存在事件绑定,执行绑定的值
调用render函数时获取vdom,发现h1存在事件绑定-> 先执行代码this.test(return <h1 onClick={this.test}>点击</h1> test(){ console.log('执行了') } </script>
函数体也是表达式,返回值为函数本身
) -> 得到test函数;
当事件被触发时,调用该函数;
因此:当点击h1时会打印执行了;
调用render函数时获取vdom,发现h1存在事件绑定-> 先执行代码this.test() -> 获取到的是undefinedreturn <h1 onClick={this.test()}>点击</h1> test(){ console.log('执行了') } </script>
当事件被触发时,无函数可执行
因此:一进入页面会打印执行了,当事件被触发时无任何变化;
- 原生js是当事件被触发时 执行 对应的逻辑代码
- 总结:
原生js事件绑定的值只有在事件被触发时才会执行
react中的事件绑定 会在render函数调用时被触发,函数的返回值才是函数被触发时执行的逻辑代码
react事件的this指向
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
class Mycomponent extends React.Component{
render(){
console.log(this) // 实例化对象
return <h1 onClick={this.test}>测试事件绑定</h1>
}
test(){
console.log(this) // undefined
}
}
ReactDOM.render(<Mycomponent />, document.getElementById('test111'))
</script>
- 事件绑定的函数的this指向的是
undefiend
- 原因:
- 当事件触发时,react会在内部
直接调用
该函数 - 因此this应该指向window;
- 但是代码在进行编译之前会先通过babel进行编译(将jsx编译为js)
- babel编译是处于严格模式下
- 因此this指向为undefiend
- 当事件触发时,react会在内部
- 但是在函数中经常通过this指向获取某些数据,因此如果想要将this指改为实例化对象
- 1.通过显示绑定-bind
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> class Mycomponent extends React.Component{ constructor(props){ super(props) // 此处this指向了实例化对象 // 【1】 寻找test方法,在原型对象中找到test方法 // 【2】通过bind将方法的this指向修改为实例化对象(注:原型对象上的test方法的this还是指向undefiend) // 【3】接收返回的方法并添加在实例化对象上 this.test = this.test.bind(this) } render(){ console.log(this) // 实例化对象 return <h1 onClick={this.test}>测试事件绑定</h1> } test(){ console.log(this) } } ReactDOM.render(<Mycomponent />, document.getElementById('test111')) </script>
- 2.通过箭头函数获取this指向(推荐)
<script type="text/babel"> class Mycomponent extends React.Component{ render(){ console.log(this) // 实例化对象 return <h1 onClick={this.test}>测试事件绑定</h1> } // 箭头函数本身没有this指向会通过作用于链寻找上一级的this指向 // 需要注意:通过赋值的方式的函数会添加在实例化对象上而不是原型对象上 test=()=>{ console.log(this) // 实例化对象 } } ReactDOM.render(<Mycomponent />, document.getElementById('test111')) </script>
- 1.通过显示绑定-bind