基础知识javascript--事件

时间:2024-01-10 09:02:56

群里有一个小伙伴在处理事件监听函数的时候,遇到了一点问题,正好我比较空闲,于是帮他指出了代码中的问题,顺便整理一下,方便以后遇到类似问题的伙伴们有一个参考。

这是一个很简单的问题,对于基础知识比较杂实的同学来说。下边用代码简单展示一下:

 var btn = document.querySelector('#btn');

 btn.addEventListener('click',function(){

     callback();

 },false);

 function callback(){
var event = event.target || event.srcElement;
console.log(event) // 为什么event为未定义?
}

这显然是未定义的,估计那个小伙伴以为event和window一样,是系统免费送的参数,看来这样用报错,于是他就在群里问起来了。然后我告诉他问题在哪里,很快,他就改好了。

 var btn = document.querySelector('#btn');

 btn.addEventListener('click',callback,false);

 function callback(event){
var event = event.target || event.srcElement;
console.log(event)
}

他开心的告诉我,问题解决了。可是问题又来了,为什么我没有在callback中传入实参,函数运行的时候也可以收到值呢?真是个爱思考的好孩纸。我决定帮他弄清楚这个问题。

于是写这篇博客来详细分析一下。

首先从

 btn.addEventListener('click',callback,false);这里看过来,这里其实只是给click事件邦定一个事件处理函数,可以看成是callback函数的一个引用,它的形参是由我们在定义callback的时候决定的。我们打开Chrome浏览器的控制台一看,就明白了:
基础知识javascript--事件
当我们点击click的时候,系统会把当前的mouseEvent事件做为callback的第一个实参传进去,相当于这样调用callback(MouseEvent)。
function callback(event){}
其实这个地方的形参随便用什么名字都无所谓,只是习惯上用event,可读性强一点,你硬要用arg1之类的名字也可以。或者你想多定义几个形参
function callback(event,arg1,arg2){} ;通过前面的分析可以知道,除了第一个参数外,其它的参数都不会被赋值,因此都为undefined.
但是我们有时候需要在事件邦定的时候,传入几个自己定义的参数怎么办呢?方法主要有以下三种:
第一种:通过bind传入追加的参数
 btn.addEventListener('click',callback.bind(btn,['a','b']),false);

基础知识javascript--事件

不过这时MouseEvent对象的位置被挤到了我们指定的参数的后面去了。所以,在我们处理callback的时候,对应的形参也要进行变化

 var btn = document.querySelector('#btn');

 btn.addEventListener('click',callback.bind(btn,['a','b']),false);

 function callback(arg1,event){
var target = event.target || event.srcElement;
console.log(arguments,event,this)
}

此时的arg1就等于['a','b'],event 等于MouseEvent,这样就达到了追加参数的目的。为什么arg1不是btn呢?这得从bind的工作原理说起,简单说,bind的第一个参数是作为函数运行时的上下文对象用的。这个和我们下面要说的第二个方法是一样的。

方法二:在不支持bind的情况下,也可以使用apply或call之类的方式,我在第一个位置传入btn,是为了保持事件回调函数的上下文为点击的元素,即callback里边的this指向btn,这是一个小技巧。或者,在callback外边再包一层  :

 btn.addEventListener('click',function(event){
callback(event,['a','b']);
},false);

不过这种方式对御载事件比较麻烦,因为用的是匿名函数,当然,还有更好的解决方法,那就是用 handleEvent 这个属性。不过它通常需要构造一个对象,比如:

var obj = {

handleEvent : function(event){

callback(event,'a','b','....')

},

click      :   function(){

   btn.addEventListener('click',this,false);

}

}

在handleEvent方法里边,给callback传参数就方便很多了,而且this始终是挂在obj下面,这是非常方便的地方。这也是我最喜欢的用法,各种舒爽谁用谁知道。

好了,关于事件的常见用法就分析到这里了,关于事件的知识还有很多,比如冒包,异步什么的,由于不是本篇的重点,就不再分析了。

如果您觉得这文章对您有帮助,请点击【推荐一下】,想跟我一起学习吗?那就【关注】我吧!