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 12 Javascript
关于用Jquery的height()、width()计算动态插入的IMG标签的宽高的问题
Dec 08 Javascript
前台js调用后台方法示例
Dec 02 Javascript
常规表格多表头查询示例
Feb 21 Javascript
php和js对数据库图片进行等比缩放示例
Apr 28 Javascript
jQuery中的编程范式详解
Dec 15 Javascript
纯javascript实现的小游戏《Flappy Pig》实例
Jul 27 Javascript
快速学习jQuery插件 Form表单插件使用方法
Dec 01 Javascript
Vuejs第六篇之Vuejs与form元素实例解析
Sep 05 Javascript
js中string和number类型互转换技巧(分享)
Nov 28 Javascript
Vue使用NProgress进度条的方法
Sep 21 Javascript
JS深入学习之数组对象排序操作示例
May 01 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 ajax 静态分页过程形式
2011/09/02 PHP
PHP判断变量是否为0的方法
2014/02/08 PHP
PHP中把stdClass Object转array的几个方法
2014/05/08 PHP
php通过session防url攻击方法
2014/12/10 PHP
thinkPHP5.0框架模块设计详解
2017/03/18 PHP
php获取'/'传参的值简单方法
2017/07/13 PHP
Cookie 注入是怎样产生的
2009/04/08 Javascript
jquery中对表单的基本操作代码
2010/07/29 Javascript
Ajax 数据请求的简单分析
2011/04/05 Javascript
图片在浏览器中底部对齐 解决方法之一
2011/11/30 Javascript
setTimeout函数兼容各主流浏览器运行执行效果实例
2013/06/13 Javascript
JavaScript对象学习经验整理
2013/10/12 Javascript
JavaScript输入邮箱自动提示实例代码
2014/01/13 Javascript
js中for in语句的用法讲解
2015/04/24 Javascript
举例说明如何为JavaScript的方法参数设置默认值
2015/11/17 Javascript
Bootstrap中的表单验证插件bootstrapValidator使用方法整理(推荐)
2016/06/21 Javascript
Angular.JS判断复选框checkbox是否选中并实时显示
2016/11/30 Javascript
微信小程序实现tab左右切换效果
2020/11/15 Javascript
Ruby使用eventmachine为HTTP服务器添加文件下载功能
2016/04/20 Python
Python 含参构造函数实例详解
2017/05/25 Python
python模拟键盘输入 切换键盘布局过程解析
2019/08/15 Python
python安装dlib库报错问题及解决方法
2020/03/16 Python
selenium与xpath之获取指定位置的元素的实现
2021/01/26 Python
使用CSS3设计地图上的雷达定位提示效果
2016/04/05 HTML / CSS
HTML5梦幻之旅——炫丽的流星雨效果实现过程
2013/08/06 HTML / CSS
init进程的作用
2012/04/12 面试题
行政助理岗位职责
2013/11/10 职场文书
给医务人员表扬信
2014/01/12 职场文书
电脑饰品店的创业计划书
2014/01/21 职场文书
科技节口号
2014/06/19 职场文书
新闻发布会活动策划方案
2014/09/15 职场文书
pytest配置文件pytest.ini的详细使用
2021/04/17 Python
python实现三次密码验证的示例
2021/04/29 Python
Vue3.0中Ref与Reactive的区别示例详析
2021/07/07 Vue.js
Python+Selenium实现读取网易邮箱验证码
2022/03/13 Python
TypeScript实用技巧 Nominal Typing名义类型详解
2022/09/23 Javascript