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语句中的CDATA标签的意义
May 09 Javascript
原生Js实现按的数据源均分时间点幻灯片效果(已封装)
Dec 28 Javascript
Jquery实现textarea根据文本内容自适应高度
Apr 03 Javascript
JavaScript中Array对象用法实例总结
Nov 29 Javascript
微信小程序 wx.uploadFile在安卓手机上面the same task is working问题解决
Dec 14 Javascript
你有必要知道的10个JavaScript难点
Jul 25 Javascript
微信小程序基于Taro的分享图片功能实践详解
Jul 12 Javascript
js实现录音上传功能
Nov 22 Javascript
微信小程序自定义模态弹窗组件详解
Dec 24 Javascript
vue中渲染对象中属性时显示未定义的解决
Jul 31 Javascript
Vue中使用wangeditor富文本编辑的问题
Feb 07 Vue.js
Vue图片裁剪组件实例代码
Jul 02 Vue.js
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 array_merge下进行数组合并的代码
2008/07/22 PHP
PHP正则表达式 /i, /is, /s, /isU等介绍
2014/10/23 PHP
php操作xml入门之xml标签的属性分析
2015/01/23 PHP
Yii框架弹出窗口组件CJuiDialog用法分析
2017/01/07 PHP
PHP判断数组是否为空的常用方法(五种方法)
2017/02/08 PHP
php注册审核重点解析(数据访问)
2017/05/23 PHP
PHP中一个有趣的preg_replace函数详解
2018/08/15 PHP
用jquery ajax获取网站Alexa排名的代码
2009/12/12 Javascript
Jquery post传递数组方法实现思路及代码
2013/04/28 Javascript
JavaScript设计模式之策略模式实例
2014/10/10 Javascript
setTimeout内不支持jquery的选择器的解决方案
2015/04/28 Javascript
浅谈关于JavaScript API设计的一些建议和准则
2015/06/24 Javascript
JS实现图片的不间断连续滚动的简单实例
2016/06/03 Javascript
ui组件之input多选下拉实现方法(带有搜索功能)
2016/07/14 Javascript
angularjs 表单密码验证自定义指令实现代码
2016/10/27 Javascript
AngularJS框架中的双向数据绑定机制详解【减少需要重复的开发代码量】
2017/01/19 Javascript
详解基于vue-router的动态权限控制实现方案
2017/09/28 Javascript
jQuery实现滚动到底部时自动加载更多的方法示例
2018/02/18 jQuery
vue.js 2.*项目环境搭建、运行、打包发布的详细步骤
2019/05/01 Javascript
在Python中使用SimpleParse模块进行解析的教程
2015/04/11 Python
pandas的object对象转时间对象的方法
2018/04/11 Python
Tensorflow实现AlexNet卷积神经网络及运算时间评测
2018/05/24 Python
Django 多表关联 存储 使用方法详解 ManyToManyField save
2019/08/09 Python
python和pywin32实现窗口查找、遍历和点击的示例代码
2020/04/01 Python
python3通过qq邮箱发送邮件以及附件
2020/05/20 Python
最简单的matplotlib安装教程(小白)
2020/07/28 Python
Ubuntu配置Pytorch on Graph (PoG)环境过程图解
2020/11/19 Python
关于安全演讲稿
2014/05/09 职场文书
学校节能减排倡议书
2014/05/16 职场文书
中学生民族团结演讲稿
2014/08/27 职场文书
党的群众路线教育实践活动总结
2014/10/30 职场文书
2014年技术员工作总结
2014/11/18 职场文书
2015毕业生简历自我评价
2015/03/02 职场文书
2016年万圣节活动总结
2016/04/05 职场文书
英镑符号 £
2022/02/17 杂记
Go语言grpc和protobuf
2022/04/13 Golang