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 相关文章推荐
图片完美缩放
Sep 07 Javascript
jQuery 1.5 源码解读 面向中高阶JSER
Apr 05 Javascript
js判断屏幕分辨率的代码
Jul 16 Javascript
再探JavaScript作用域
Sep 24 Javascript
JQuery+Ajax实现数据查询、排序和分页功能
Sep 27 Javascript
AngularJs expression详解及简单示例
Sep 01 Javascript
js图片轮播手动切换特效
Jan 12 Javascript
AngularJS实现动态添加Option的方法
May 17 Javascript
实现elementUI表单的全局验证的方法步骤
Apr 29 Javascript
vue项目中实现缓存的最佳方案详解
Jul 11 Javascript
JS常用正则表达式超全集(密码强度校验,金额校验,IE版本,IPv4,IPv6校验)
Feb 03 Javascript
JS代码检查工具ESLint介绍与使用方法
Feb 04 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环境――Appserv
2006/12/13 PHP
同台服务器使用缓存APC效率高于Memcached的演示代码
2010/02/16 PHP
PHP 导出数据到淘宝助手CSV的方法分享
2010/02/27 PHP
php输出指定时间以前时间格式的方法
2015/03/21 PHP
老生常谈PHP中的数据结构:DS扩展
2017/07/17 PHP
javascript IFrame 强制刷新代码
2009/07/23 Javascript
js实现addClass,removeClass,hasClass的函数代码
2011/07/13 Javascript
使用jQuery和Bootstrap实现多层、自适应模态窗口
2014/12/22 Javascript
Javascript基础教程之变量
2015/01/18 Javascript
javascript中SetInterval与setTimeout的定时器用法
2015/08/24 Javascript
微信小程序实现图片预加载组件
2017/01/18 Javascript
图解Javascript——作用域、作用域链、闭包
2017/03/21 Javascript
微信小程序如何获取openid及用户信息
2018/01/26 Javascript
基于vue中解决v-for使用报红并出现警告的问题
2018/03/03 Javascript
你不可不知的Vue.js列表渲染详解
2019/10/01 Javascript
Javascript和jquery在selenium的使用过程
2019/10/31 jQuery
python脚本实现分析dns日志并对受访域名排行
2014/09/18 Python
Python实现Youku视频批量下载功能
2017/03/14 Python
Python实现类的创建与使用方法示例
2017/07/25 Python
详解Python nose单元测试框架的安装与使用
2017/12/20 Python
Python读取txt某几列绘图的方法
2018/10/14 Python
对Python3+gdal 读取tiff格式数据的实例讲解
2018/12/04 Python
详解python中@的用法
2019/03/27 Python
Django项目主urls导入应用中views的红线问题解决
2019/08/10 Python
Python实现图片识别加翻译功能
2019/12/26 Python
解决Python pip 自动更新升级失败的问题
2020/02/21 Python
什么是CSS3 HSLA色彩模式?HSLA模拟渐变色条
2016/04/26 HTML / CSS
css3媒体查询中device-width和width的区别详解
2020/03/27 HTML / CSS
Marlies Dekkers内衣美国官方网上商店:高端内衣品牌
2018/11/12 全球购物
乡镇计划生育工作汇报
2014/10/28 职场文书
2015年人力资源工作总结
2015/04/08 职场文书
入党积极分子党小组意见
2015/06/02 职场文书
南京南京观后感
2015/06/02 职场文书
Redis做数据持久化的解决方案及底层原理
2021/07/15 Redis
Java面试题冲刺第十七天--基础篇3
2021/08/07 面试题
win10更新失败无限重启解决方法
2022/04/19 数码科技