之前做笔记写了两个关于事件的玩意,称之为玩意是当时只是很潦草的记录了一下当时的想法。现在做一个完善总结
文章目录
一、什么是事件
1. 先看怎么我们写事件绑定是怎么写的
<body>
<button id="btn0" onclick="console.log('0')"> 猛一点我 </button> //-----------------第一种方式
<button id="btn00" onclick="test()"> dianwo </button>//----------------------------第二种方式
<button id="btn1"> click me </button>//--------------------------------------------第三种方式
<button id="btn2"> CLICK2 </button>//----------------------------------------------第四种方式
<script>
btn1.onclick = function () {
console.log("竟敢点我!!!");
};
btn2.addEventListener("click", () => {
console.log("gege~WOW~~");
});
function test() {
console.log("00");
}
</script>
这四个按钮依次点击输出的是
2. 区别
dom0级绑定依赖dom对象上的onclick属性
① 要是按照方式一
的写法会将红色部分作为参数传入dom对象上的onclick属性里面(此属性是个函数)
② 第二个按钮<button id="btn00" onclick="test()">dianwo</button>
其test函数和上面同理
。
③ 第三种方式: btn是拿到的这个按钮,也就是dom对象。var obj = {};obj.fun = function (){..}
这种写法是往对象身上添加一个方法,那这里一样的道理用自己写的onclick函数替换了dom对象上原本的那个属性
④dom2级事件
方法四不再依赖onclick这个属性,而是通过addEventListener来注册事件。
思考方式二的test为什么要加()
3. 什么是事件
简单来说事件是浏览器产生的一条操作记录,虽然第二个按钮绑定了test函数,但并不是说我在后面加一句test()来执行这个函数就代表事件触发了
function test() {
console.log("00");
}
test()//----------------这个仅仅表示test这个函数执行了
能触发事件的有很多,用户的操作,网页上的机器人程序等等…dom0级事件中,事件触发后会执行onclick函数。dom2级中是靠EventTarget(它有个方法就是addEventListener)这个接口实现。思考问题中要加()是因为我们写的test函数也要在事件触发后执行了onclick函数再执行text()。
二、同步还是异步的问题
因为用户的点击,这种行为发生的时间很随意。如果是同步的,那么就得事件触发后才执行下面的代码。要是我永远不点这个按钮呢???所以注定事件只可能是异步
在我刚开始学习的时候就会觉得onclick函数就代表者事件,记住我们写的代码(如test函数)都不是事件,最多只能是事件触发后要执行的操作
三、框架中绑定事件的具体表现以及this丢失问题
回调函数中this指向会出现丢失,严格模式下为undifinde—《你不知道的JavaScript》
1.原生js this丢失问题
①. 刚刚说了在html页面使用的onclick是个全局属性,=号后面的值<button onclick=''>
会被当做参数传递给onclick这个全局属性在这里插入图片描述
关键点在于,这里必须传递一个函数的执行,而不是一个函数。既然是函数的执行,其函数内部的this就已经指定。(this是运行时产生的上下文环境对象)
②. 再看回调函数中的this丢失
function aa(event) {
event();
}
let obj = {
bb() {
console.log(this, "aabb");
},
};
aa(obj.bb);
这种情况是将obj.bb也就是bb这个函数当做参数传递进了aa,函数作为一个引用类型其地址是不变的它是自由的传给是就是谁的。
obj.bb()这样执行this就是obj,this记录了函数由obj执行
this是一个运行时产生的上下文环境对象,其中记录了函数的由谁执行,怎样执行等行为。这个时候传递的其实是个函数,这个函数交给了另外的形参event去执行,当没有任何修饰的时候去执行一个函数时往往内部this指向window 。没有任何修饰指的是执行时不是xxx.fun()这种新形式。this记录了函数由window对象执行。
2.React中的事件绑定this问题
react 的onClick传递的并不是一个函数执行不要将其想象成html上的onclick
其实百度一搜就能了解dom0级绑定缺点多多。这里事件也是通过EventTarget接口来实现,所以当做一种回调形式或者说传的是函数
是会出现this丢失的。为了解决这种问题,在react自定义事件中得用箭头函数的方式去书写。
小小总结:
①.页面元素的dom对象上有onclcik属性,如果是用这种方式绑定事件,事件触发(异步)执行的是这个的是这个onclick方法,直接在html页面写就得传个函数执行好让onclick方法执行的时候这个处理函数也执行,或者在script标签中重写次方法–btn.onclick = function(){…}
②.回调函数中确实是会出现this丢失,addeventlisner是重新绑定到了dom元素,react用箭头函数解决
3.Vue中事件绑定this问题
vue中方法总在method里面,其方法的this指向当前组件实例, <button v-on:click="greet">Greet</button>
这个greet加不加()都行。不加其实是默认不带参数的,也就是说vue框架为了让你偷懒,就算你不加括号也是greet()
进一步总结:
①.vue中就很符合原生,v-on绑定个函数执行,但多了个不写()默认为不传参执行,框架给你改this指向,框架给你注册事件。
②.react不一样,更加符合直觉。用户点击就触发你写的函数
。函数在执行时传参,但用户点击是异步且不确定的,默认的参数传递就需要通过包裹一层函数或者bind方法来解决,有兴趣可以搜搜函数柯里化。
回归正题:
①.框架中的v-on或者onClick都与原生js里的dom0级事件绑定很像,但实际上与onclick这个属性无关所以不是dom0级事件绑定。②vue传递的是函数执行,react传递的是函数,传的是函数就会出现this丢失的问题。注意不是传递给onclick,是在EventTarget上的addeventlistener。