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 相关文章推荐
JS应用之禁止抓屏、复制、打印
Feb 21 Javascript
JS判断数组中是否有重复值得三种实用方法
Aug 16 Javascript
WEB前端实现裁剪上传图片功能
Oct 17 Javascript
node.js实现回调的方法示例
Mar 01 Javascript
微信小程序实现换肤功能
Mar 14 Javascript
Element-UI Table组件上添加列拖拽效果实现方法
Apr 14 Javascript
JS实现点击拉拽轮播图pc端移动端适配
Sep 05 Javascript
JS重学系列之聊聊new操作符
Mar 04 Javascript
Vue基础学习之项目整合及优化
Jun 02 Javascript
JavaScript设计模式--桥梁模式引入操作实例分析
May 23 Javascript
利用webpack理解CommonJS和ES Modules的差异区别
Jun 16 Javascript
vant 解决tab切换插件标题样式自定义的问题
Nov 13 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排序算法的复习和总结
2012/02/15 PHP
PHP获取本周第一天和最后一天示例代码
2014/02/24 PHP
jQuery select操作控制方法小结
2010/05/26 Javascript
javascript静态页面传值的三种方法分享
2013/11/12 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
2015/02/04 Javascript
AngularJS基础学习笔记之简单介绍
2015/05/10 Javascript
AngularJS模块详解及示例代码
2016/08/17 Javascript
教你一步步用jQyery实现轮播器
2016/12/18 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
2017/02/05 Javascript
js自定义Tab选项卡效果
2017/06/05 Javascript
JQuery form表单提交前验证单选框是否选中、删除记录时验证经验总结(整理)
2017/06/09 jQuery
浅谈angular2 组件的生命周期钩子
2017/08/12 Javascript
vue实现全选和反选功能
2017/08/31 Javascript
BootStrap中的模态框(modal,弹出层)功能示例代码
2018/11/02 Javascript
微信小程序Echarts覆盖正常组件问题解决
2019/07/13 Javascript
node.js 微信开发之定时获取access_token
2020/02/07 Javascript
webpack.DefinePlugin与cross-env区别详解
2020/02/23 Javascript
Python随机生成彩票号码的方法
2015/03/05 Python
Python实现从百度API获取天气的方法
2015/03/11 Python
Python中encode()方法的使用简介
2015/05/18 Python
用pandas中的DataFrame时选取行或列的方法
2018/07/11 Python
pycharm无法安装第三方库的问题及解决方法以scrapy为例(图解)
2020/05/09 Python
使用CSS3的appearance属性改变元素的外观的方法
2015/12/12 HTML / CSS
H5 canvas实现贪吃蛇小游戏
2017/07/28 HTML / CSS
Bobbi Brown芭比波朗美国官网:化妆师专业彩妆保养品品牌
2016/08/18 全球购物
培训主管岗位职责
2014/02/01 职场文书
幼儿发展评估方案
2014/06/11 职场文书
低碳日宣传活动总结
2014/07/09 职场文书
三八妇女节趣味活动方案
2014/08/23 职场文书
2014广电局实施党的群众路线教育实践活动方案思想汇报
2014/09/22 职场文书
初中教师个人工作总结
2015/02/10 职场文书
2015年统计员个人工作总结
2015/07/23 职场文书
保姆聘用合同
2015/09/21 职场文书
《曾国藩家书》读后感——读家书,立家风
2019/08/21 职场文书
解决tk mapper 通用mapper的bug问题
2021/06/16 Java/Android
MySQL系列之十五 MySQL常用配置和性能压力测试
2021/07/02 MySQL