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 相关文章推荐
JavaScript下申明对象的几种方法小结
Oct 02 Javascript
Jquery中国地图热点效果-鼠标经过弹出提示层信息的简单实例
Feb 12 Javascript
node.js中的path.extname方法使用说明
Dec 09 Javascript
JavaScript实现同步于本地时间的动态时间显示方法
Feb 02 Javascript
基于jQuery实现仿百度首页换肤背景图片切换代码
Aug 25 Javascript
浅析javascript中的事件代理
Nov 06 Javascript
微信小程序实现人脸检测功能
May 25 Javascript
JS面向对象的程序设计相关知识小结
May 26 Javascript
React注册倒计时功能的实现
Sep 06 Javascript
elementUI 设置input的只读或禁用的方法
Oct 30 Javascript
JavaScript之解构赋值的理解
Jan 30 Javascript
vue实现五子棋游戏
May 28 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
Codeigniter+PHPExcel实现导出数据到Excel文件
2014/06/12 PHP
php实现批量上传数据到数据库(.csv格式)的案例
2017/06/18 PHP
基于Laravel实现的用户动态模块开发
2017/09/21 PHP
详解提高使用Java反射的效率方法
2019/04/29 PHP
Nigma vs Alliance BO5 第三场2.14
2021/03/10 DOTA
jQuery-Tools-overlay 使用介绍
2012/07/14 Javascript
JS中attr和prop属性的区别以及优先选择示例介绍
2014/06/30 Javascript
18个非常棒的jQuery代码片段
2015/11/02 Javascript
onmouseover事件和onmouseout事件全面理解
2016/08/15 Javascript
利用jQuery实现打字机字幕效果实例代码
2016/09/02 Javascript
javascript实现动态显示颜色块的报表效果
2017/04/10 Javascript
基于AngularJS的拖拽文件上传的实例代码
2017/07/15 Javascript
详解angular笔记路由之angular-router
2017/09/12 Javascript
vue2.0 下拉框默认标题设置方法
2018/08/22 Javascript
原生javascript自定义input[type=radio]效果示例
2019/08/27 Javascript
使用Taro实现小程序商城的购物车功能模块的实例代码
2020/06/05 Javascript
[01:15:00]LGD vs Mineski Supermajor 胜者组 BO3 第一场 6.5
2018/06/06 DOTA
ERLANG和PYTHON互通实现过程详解
2019/07/05 Python
nginx搭建基于python的web环境的实现步骤
2020/01/03 Python
Python查找不限层级Json数据中某个key或者value的路径方式
2020/02/27 Python
Python 随机生成测试数据的模块:faker基本使用方法详解
2020/04/09 Python
python爬虫数据保存到mongoDB的实例方法
2020/07/28 Python
python3.7.3版本和django2.2.3版本是否可以兼容
2020/09/01 Python
如何使用Python进行PDF图片识别OCR
2021/01/22 Python
如何利用input事件来监听移动端的输入
2016/04/15 HTML / CSS
HTML5新标签兼容——&gt; 的两种方法
2018/09/12 HTML / CSS
写一个用矩形法求定积分的通用函数
2012/11/08 面试题
介绍一下write命令
2012/09/24 面试题
PHP引擎php.ini参数优化深入讲解
2021/03/24 PHP
毕业生物理教师求职信
2013/10/17 职场文书
旅游个人求职信范文
2014/01/30 职场文书
工作说明书范文
2014/05/07 职场文书
初中生思想道德自我评价
2015/03/09 职场文书
网络营销实训总结
2015/08/03 职场文书
python编程实现清理微信重复缓存文件
2021/11/01 Python
vue2的 router在使用过程中遇到的一些问题
2022/04/13 Vue.js