js使用函数绑定技术改变事件处理程序的作用域


Posted in Javascript onDecember 26, 2011

第一种,也是 最常见的,就是直接在html标签里面通过指定事件处理程序同名的HTML属性来注册事件,代码如下:

function eventHandler() { 
alert("当前作用域是 input 元素本身"); 
} 
<input type="button" value="单击我" onclick="eventHandler(this)"/>

第二种方式就是将一个函数赋值给一个事件处理程序属性。这种方式首先的获取到这个元素对象,一般代码如下:
<input id="myEventHandlerScope" type="button" value="单击我"/> 
<script type="text/javascript"> 
function eventHandler() { 
alert("当前作用域是 input 元素本身"); 
} 
var mybtn = document.getElementById("myEventHandlerScope"); 
mybtn.onclick = eventHandler; 
</script>

第三种方式,就是理由DOM2级别的事件处理方法 addEventListener和removeEventListener,针对ie浏览器对应的方法是attachEvent 和 detachEvent。注册事件的代码如下:
<input id="myEventHandlerScope" type="button" value="单击我"/> 
<script type="text/javascript"> 
//定义一个注册事件的方法 
function addHandler(obj, type, handler) { 
if (obj.addEventListener) { 
obj.addEventListener(type, handler, false); 
} else if (obj.attachEvent) { 
obj.attachEvent("on" + type, handler); 
} else { 
obj["on" + type] = handler; 
} 
} 
function eventHandler() { 
alert("当前作用域是 input 元素本身"); 
} 
var mybtn = document.getElementById("myEventHandlerScope"); 
addHandler(mybtn,'click',eventHandler);//为对象注册事件 
</script>

js使用函数绑定技术改变事件处理程序的作用域
通过以上3种方式为input元素注册一个 click 事件处理程序都有一个缺点就是这个处理程序的作用域(this)始终处于input对象。在面向对象编程的时候,就需要明确的指定this在特定的作用域下面。 为了改变this的作用域,就得用到js的一种绑定函数技术。
所谓“绑定函数”就是要创建一个函数,可以在特定环境中以指定参数调用另一个函数,他能很好的与事件处理程序一起使用,以便在将函数作为变量传递的同时保持函数的作用域(也是this的执行环境)。绑定函数的定义形式如下代码:

function bind(fn,scope) { 
return fn.apply(scope||this,arguments); 
}

这个绑定函数接受两个参数,第一个是需要执行的函数,第二个是特定的执行环境,并返回一个在给定作用域中调用给定函数,并将所有参数一同传递过去。利用绑定函数技术和DOM2级的事件处理程序就能很好的为元素注册一个在特定作用域下执行的事件处理函数。具体的处理方式如下:
首先修改先前定义的注册事件的方法如下代码:
function addHandler(obj, type, handler, scope) { 
function fn(event) { 
var evt = event ? event : window.event; 
evt.target = event.target || event.srcElement; 
return handler.apply(scope || this,arguments); 
} 
obj.eventHash = obj.eventHash || {};//这里为需要注册事件处理程序的对象定义一个保存事件的hash对象,并把事件处理程序和作用域保存在该事件类型的队列里面 
(obj.eventHash [type] = obj.eventHash [type] || []).push({ "name": type, "handler": handler, "fn": fn, "scope": scope }); 
if (obj.addEventListener) { 
obj.addEventListener(type, fn, false); 
} else if (obj.attachEvent) { 
obj.attachEvent("on" + type, fn); 
} else { 
obj["on" + type] = fn; 
} 
}

使用修改后的注册事件方法就可以使元素的事件处理程序在指定的环境里面执行了。
<input id="myEventHandlerScope" type="button" value="单击我"/> 
<script type="text/javascript"> 
function eventHandler() { 
this; 
alert("当前作用域是 window 元素本身"); 
} 
var mybtn = document.getElementById("myEventHandlerScope"); 
addHandler(mybtn, 'click', eventHandler,window); 
</script>

执行上面这段代码,处理程序eventHandler的this作用域就处在了window对象下面。

js使用函数绑定技术改变事件处理程序的作用域

在前面介绍的通过绑定函数注册事件是为元素对象创建了一个事件的hash对象用来保存事件处理程序,这个hash对象在元素移除事件处理程序的时候起到了非常总要左右,根据他就能准确的移除对应的事件处理程序。移除事件处理程序的代码如下:
function removeHandler (obj, type, handler, scope) { 
obj.eventHash = obj.eventHash || {}; 
var evtList = obj.eventHash [type] || [], len = evtList.length; 
if (len > 0) { 
for (; len--; ) { 
var curEvtObj = evtList[len]; 
if (curEvtObj.name == type && curEvtObj.handler === handler && curEvtObj.scope === scope) { 
if (obj.removeEventListener) { 
obj.removeEventListener(type, curEvtObj.fn, false); 
} else if (obj.detachEvent) { 
obj.detachEvent("on" + type, curEvtObj.fn); 
} else { 
obj["on" + type] = null; 
} 
evtList.splice(len, 1); 
break; 
} 
} 
} 
}

到这里就介绍完了使用函数绑定技术注册特定执行环境的事件处理程序。同样,利用函数绑定还能使回调函数在给定的执行环境里面执行。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

Javascript 相关文章推荐
一步一步制作jquery插件Tabs实现过程
Jul 06 Javascript
Jquery下判断Id是否存在的代码
Jan 06 Javascript
jquery批量设置属性readonly和disabled的方法
Jan 24 Javascript
jquery的ajax异步请求接收返回json数据实例
Jun 16 Javascript
jQuery使用$.get()方法从服务器文件载入数据实例
Mar 25 Javascript
JS自定义混合Mixin函数示例
Nov 26 Javascript
Vue shopCart 组件开发详解
Jan 26 Javascript
vue结合Echarts实现点击高亮效果的示例
Mar 17 Javascript
基于jQuery使用Ajax动态执行模糊查询功能
Jul 05 jQuery
vue中datepicker的使用教程实例代码详解
Jul 08 Javascript
layui实现把数据表格时间戳转换为时间格式的例子
Sep 12 Javascript
vue使用@scroll监听滚动事件时,@scroll无效问题的解决方法详解
Oct 15 Javascript
JavaScript中的property和attribute介绍
Dec 26 #Javascript
JavaScript打字小游戏代码
Dec 26 #Javascript
js bind 函数 使用闭包保存执行上下文
Dec 26 #Javascript
js 函数调用模式小结
Dec 26 #Javascript
JavaScript 原型继承
Dec 26 #Javascript
jquery事件机制扩展插件 jquery鼠标右键事件。
Dec 26 #Javascript
查看源码的工具 学习jQuery源码不错的工具
Dec 26 #Javascript
You might like
解析PHP对现有搜索引擎的调用
2013/06/25 PHP
PHP实现简单爬虫的方法
2015/07/29 PHP
PHP连接MSSQL方法汇总
2016/02/05 PHP
PHP实现多图上传(结合uploadify插件)思路分析
2016/11/30 PHP
Laravel使用消息队列需要注意的一些问题
2017/12/13 PHP
php empty 函数判断结果为空但实际值却为非空的原因解析
2018/05/28 PHP
Jquery 插件开发笔记整理
2011/01/17 Javascript
js判断复选框是否选中及选中个数的实现代码
2016/05/30 Javascript
深入理解jQuery事件绑定
2016/06/02 Javascript
javascript与jquery动态创建html元素示例
2016/07/25 Javascript
JavaScript实战(原生range和自定义特效)简单实例
2016/08/21 Javascript
微信小程序 flex实现导航实例详解
2017/04/26 Javascript
详解Vue中一种简易路由传参办法
2017/09/15 Javascript
基于vue 实现token验证的实例代码
2017/12/14 Javascript
基于Node.js实现压缩和解压缩的方法
2018/02/13 Javascript
详解webpack4.x之搭建前端开发环境
2019/03/28 Javascript
javascript(基于jQuery)实现鼠标获取选中的文字示例【测试可用】
2019/10/26 jQuery
浅谈vue中$bus的使用和涉及到的问题
2020/07/28 Javascript
[36:22]VP vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
在Python中marshal对象序列化的相关知识
2015/07/01 Python
在Django框架中设置语言偏好的教程
2015/07/27 Python
python 打印出所有的对象/模块的属性(实例代码)
2016/09/11 Python
PyQt5实现五子棋游戏(人机对弈)
2020/03/24 Python
Python使用pandas和xlsxwriter读写xlsx文件的方法示例
2019/04/09 Python
关于Django Models CharField 参数说明
2020/03/31 Python
python函数调用,循环,列表复制实例
2020/05/03 Python
利用scikitlearn画ROC曲线实例
2020/07/02 Python
如何解决flask修改静态资源后缓存文件不能及时更改问题
2020/08/02 Python
python 将列表里的字典元素合并为一个字典实例
2020/09/01 Python
CSS 说明横向进度条最后显示文字的实现代码
2020/11/10 HTML / CSS
HTML5中微数据概述及在搜索引擎中的使用举例
2013/02/07 HTML / CSS
ruby如何进行集成操作?Ruby能进行多重继承吗?
2013/10/16 面试题
保护黄河倡议书
2014/05/16 职场文书
小学生感恩老师演讲稿
2014/08/28 职场文书
python字典的元素访问实例详解
2021/07/21 Python
Python办公自动化解决world文件批量转换
2021/09/15 Python