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数字数组去重复项的实现代码
Dec 30 Javascript
深入理解JavaScript系列(8) S.O.L.I.D五大原则之里氏替换原则LSP
Jan 15 Javascript
jQuery UI Dialog 创建友好的弹出对话框实现代码
Apr 12 Javascript
JavaScript中几种排序算法的简单实现
Jul 29 Javascript
js将滚动条滚动到指定位置的简单实现方法
Jun 25 Javascript
Jquery Easyui表单组件Form使用详解(30)
Dec 19 Javascript
JavaScript之map reduce_动力节点Java学院整理
Jun 29 Javascript
vue-resource + json-server模拟数据的方法
Nov 02 Javascript
在vue2.0中引用element-ui组件库的方法
Jun 21 Javascript
Angular异步变同步处理方法
Aug 13 Javascript
vue中子组件传递数据给父组件的讲解
Jan 27 Javascript
JavaScript实现多文件下载方法解析
Aug 07 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将URL转换成短网址的算法分享
2016/09/13 PHP
php数据库的增删改查 php与javascript之间的交互
2017/08/31 PHP
给Function做的OOP扩展
2009/05/07 Javascript
最新28个很棒的jQuery 教程
2011/05/28 Javascript
javascript开发随笔二 动态加载js和文件
2011/11/25 Javascript
让新消息在网页标题闪烁提示的jQuery代码
2013/11/04 Javascript
js 赋值包含单引号双引号问题的解决方法
2014/02/26 Javascript
JS+CSS实现的蓝色table选项卡效果
2015/10/08 Javascript
js实现仿微博滚动显示信息的效果
2015/12/21 Javascript
运用js教你轻松制作html音乐播放器
2020/04/17 Javascript
bootstrap table表格客户端分页实例
2017/08/07 Javascript
React-Native之定时器Timer的实现代码
2017/10/04 Javascript
微信小程序实现指定显示行数多余文字去掉用省略号代替
2018/07/25 Javascript
详解关于表格合并span-method方法的补充(表格数据由后台动态返回)
2019/05/21 Javascript
判断“命令按钮”是否被鼠标单击详解
2019/07/31 Javascript
React Hooks 实现和由来以及解决的问题详解
2020/01/17 Javascript
基于原生js实现判断元素是否有指定class名
2020/07/11 Javascript
js正则表达式简单校验方法
2021/01/03 Javascript
简单介绍使用Python解析并修改XML文档的方法
2015/10/15 Python
使用Python编写爬虫的基本模块及框架使用指南
2016/01/20 Python
python实现requests发送/上传多个文件的示例
2018/06/04 Python
Python字符串的常见操作实例小结
2019/04/08 Python
用python生成(动态彩色)二维码的方法(使用myqr库实现)
2019/06/24 Python
python写入数据到csv或xlsx文件的3种方法
2019/08/23 Python
python GUI库图形界面开发之PyQt5中QMainWindow, QWidget以及QDialog的区别和选择
2020/02/26 Python
Python常用编译器原理及特点解析
2020/03/23 Python
python中_del_还原数据的方法
2020/12/09 Python
俄罗斯香水在线商店:AromaCode
2019/12/04 全球购物
销售人员自我评价
2014/02/01 职场文书
《晏子使楚》教学反思
2014/02/08 职场文书
教师党员先进性教育自我剖析材料思想汇报
2014/09/24 职场文书
帝企鹅日记观后感
2015/06/10 职场文书
建立共青团委员会的请示
2019/04/02 职场文书
如何让2019年上半年的工作总结更出色!
2019/07/01 职场文书
CSS3 实现的图片悬停的切换按钮
2021/04/13 HTML / CSS
Vue监视数据的原理详解
2022/02/24 Vue.js