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

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

 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浏览器的控制台一看,就明白了:

当我们点击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);

不过这时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下面,这是非常方便的地方。这也是我最喜欢的用法,各种舒爽谁用谁知道。

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

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

基础知识javascript--事件的更多相关文章

  1. 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, VerticalAlignment

    [源码下载] 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, Vertical ...

  2. C#基础知识之事件和委托

    本文中,我将通过两个范例由浅入深地讲述什么是委托.为什么要使用委托.委托的调用方式.事件的由来..Net Framework中的委托和事件.委托和事件对Observer设计模式的意义,对它们的中间代码 ...

  3. JavaScript 基础知识梳理——事件

    事件 1)事件是文档或浏览器窗口中发生的特定的交互瞬间. JavaScript和HTML之间的交互是通过事件实现的. 2)事件流——描述的是从页面中接受事件的顺序 IE——事件冒泡流 Netscape ...

  4. JavaScript 之基础知识

    JavaScript 基础知识 JavaScript 是属于网络的脚本语言! JavaScript 被数百万计的网页用来改进设计.验证表单.检测浏览器.创建cookies,以及更多的应用. JavaS ...

  5. JS基础知识:Javascript事件触发列表

    Javascript是一种由Netscape的LiveScript发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言. JavaScript使我们有能 ...

  6. javascript中BOM部分基础知识总结

    一.什么是BOM      BOM(Browser Object Document)即浏览器对象模型.      BOM提供了独立于内容 而与浏览器窗口进行交互的对象:      由于BOM主要用于管 ...

  7. (转)JAVA AJAX教程第二章-JAVASCRIPT基础知识

    开篇:JAVASCRIPT是AJAX技术中不可或缺的一部分,所以想学好AJAX以及现在流行的AJAX框架,学好JAVASCRIPT是最重要的.这章我给大家整理了一些JAVASCRIPT的基础知识.常用 ...

  8. 学习javascript基础知识系列第二节 - this用法

    通过一段代码学习javascript基础知识系列 第二节 - this用法 this是面向对象语言中的一个重要概念,在JAVA,C#等大型语言中,this固定指向运行时的当前对象.但是在javascr ...

  9. 《JAVASCRIPT高级程序设计》表单基础知识和文本框脚本

    在HTML中,表单是由<form>元素来表示,在javascript中,表单对应的是HTMLFormElement类型,它具有一些独有的属性和方法: 一.表单基础知识 1.取得表单的方式 ...

  10. JavaScript基础知识从浅入深理解(一)

    JavaScript的简介 javascript是一门动态弱类型的解释型编程语言,增强页面动态效果,实现页面与用户之间的实时动态的交互. javascript是由三部分组成:ECMAScript.DO ...

随机推荐

  1. Torch7学习笔记(三)Sequencialization

    1.序列化 Torch提供4种高级方法来序列化或者反序列化任意Lua/Torch对象.这些方法都是从File对象抽象出来的,为了方便操作而创建. 前两种方法用来从文件序列化或者反序列化的: torch ...

  2. [LintCode] Sort List 链表排序

    Sort a linked list in O(n log n) time using constant space complexity. Have you met this question in ...

  3. Odoo 报表中添加空格

    如果  不起作用,请用 代替.

  4. SharePoint 2010中一些必须知道的限制

    最大文件名长度是123个字符. 一个文档库(library)里最多可以存放10000个文档 一个视图(view)里最多显示5000个条目(item) 推荐的单个内容数据库(content databa ...

  5. Linux 部署ASP.NET SQLite 应用 的坎坷之旅 附demo及源码

    Linux 部署ASP.NET SQLite 应用 的坎坷之旅.文章底部 附示例代码. 有一台闲置的Linux VPS,尝试着部署一下.NET 程序,结果就踏上了坑之路,不过最后算是完美解决问题,遂记 ...

  6. 分享一个css3写的气泡对话框,适合于即时通讯和留言本的动态内容

    效果预览: css code .message_content{width:100%;margin-top:10px;clear:both;float:left;} .face{float:left; ...

  7. 在Github上搭建自己的博客(Windows平台)

    折腾了好久,终于在Github上搭建了自己的博客.这里面总结一下过程希望对大家能有所帮助. Github建博优缺点 和 csdn,新浪,网易相比,在Github上可以自己实现功能 和阿里云,VPS相比 ...

  8. SQL Azure (15) SQL Azure 新的规格

    <Windows Azure Platform 系列文章目录> 在以前的文章中,笔者给大家介绍了Microsoft Azure SQL Database (以前被称为SQL Azure)的 ...

  9. windows命令——explorer

    转至http://www.cnblogs.com/ymind/archive/2012/03/30/explorer-command-args.html 今天才知道,explorer原来可以这样用, ...

  10. 每天一个linux命令(26):用SecureCRT来上传和下载

    用SSH管理linux服务器时经常需要远程与本地之间交互文件.而直接用SecureCRT自带的上传下载功能无疑是最方便的,SecureCRT下的文件传输协议有ASCII.Xmodem.Zmodem.文 ...