具体谈如何实现JS为句柄添加监听函数之前先看一段代码,算是抛出这个问题。

<html>
<head>
<title>JS为句柄添加监听函数</title> <script>
function message(){
alert("hello!");
}
</script>
</head>
<body>
<center>
<div onclick="message();"><p>JavaScript</p></div>
</center>
</body>
</html>

程序代码本身的运行是不会有问题的。不过我的着眼点在于CSS是为了让html文档结构和变现分离,JavaScript着眼于文档结构和行为的分离,上面带按摩并未做到文档结构和行为的彻底分离(div上指明了onclick事件)。

接下来就是如何在js中实现对div添加onclick监听函数。

JS实现行为、结构分离

其实在JavaScript中为DOM元素绑定事件监听函数是一件非常常见的事情,但是这里也有许多bug。各种浏览器对于事件的绑定都提供了很多的方法,但是可靠的只有3种:

传统绑定:

<html><head>
<title>JS为句柄添加监听函数</title> <script>
function message(message) {
alert(message);
} window.onload = function() {
var div = document.getElementById("div");
div.onclick = function(event) {
message(event.type);
};
}
</script></head><body>
<center>
<div id="div">
<p>JavaScript</p>
</div>
</center></body></html>

A:传统的绑定方法,非常简单稳定,而且函数体内的this就是正在处理事件的节点。

B:一个元素的事件句柄只能注册一个函数,重复注册会产生覆盖;而且传统的绑定只会在事件冒泡中运行。

Tips:事件冒泡:当一个元素上的事件触发时,同样的事件会在该元素的所有祖先元素中触发。该事件从元素一直冒泡到DOM树的最上层,这一过程称为事件冒泡。

W3C标准绑定:

<html><head>
<title>JS为句柄添加监听函数</title> <script>
function message(message) {
alert(message);
} window.onload = function() {
var div = document.getElementById("div");
//注册监听函数
div.addEventListener('click',function(event){
message(event.type+" hello");
},false);
//重复注册监听函数
div.addEventListener('click',function(event){
message(event.type+" world");
},false);
}
</script></head><body>
<center>
<div id="div">
<p>JavaScript</p>
</div>
</center></body></html>

A、这种绑定方法同时支持事件处理的捕获和冒泡两个阶段;同一元素的同一事件句柄可以注册多个监听函数;而且内部this指向当前元素

Tips:adEventListener中的第三个额参数为false(冒泡获取由里向外)|true(由外向里)

B、我大IE不支持这种注册方法。

IE绑定:

<html><head>
<title>JS为句柄添加监听函数</title> <script>
function message(message) {
alert(message);
} window.onload = function() {
var div = document.getElementById("div");
//注册监听函数
div.attachEvent('onclick',
function() {
message(window.event.srcElement.innerHTML + ' ' + this.innerHTML + 1);
}
);
//重复注册监听函数
div.attachEvent('onclick',
function() {
message(window.event.srcElement.innerHTML + ' ' + this.innerHTML + 2);
}
);
}
</script></head><body>
<center>
<div id="div">
<p>JavaScript</p>
</div>
</center></body></html>

A:这种绑定方法,可以为同一事件句柄注册多次。

B:IE的事件模型不支持事件捕获;监听函数体内的this指向的不表示当前元素,而且window.event.srcElement指向的是发生事件的节点,而不是当前节点。

除了强烈的吐槽一下IE浏览器之外,我们也只能静下心来寻求一种兼容的方法了,接下来介绍两种方法:

跨浏览器方法一:

function addEvent(element, type, handler) {
if (!handler.$$guid) handler.$$guid = addEvent.guid++;
if (!element.events) element.events = {};
var handlers = element.events[type];
if (!handlers) {
handlers = element.events[type] = {};
if (element["on" + type]) {
handlers[0] = element["on" + type];
}
}
handlers[handler.$$guid] = handler;
element["on" + type] = handleEvent;
};
addEvent.guid = 1; function removeEvent(element, type, handler) {
if (element.events && element.events[type]) {
delete element.events[type][handler.$$guid];
}
};
function handleEvent(event) {
var returnValue = true;
event = event || fixEvent(window.event);
var handlers = this.events[event.type];
for (var i in handlers) {
this.$$handleEvent = handlers[i];
if (this.$$handleEvent(event) === false) {
returnValue = false;
}
}
return returnValue;
}; function fixEvent(event) {
event.preventDefault = fixEvent.preventDefault;
event.stopPropagation = fixEvent.stopPropagation;
return event;
};
fixEvent.preventDefault = function() {
this.returnValue = false;
};
fixEvent.stopPropagation = function() {
this.cancelBubble = true;
};

参考:http://dean.edwards.name/weblog/2005/10/add-event2/

跨浏览器方法二:

function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
obj.attachEvent( 'on'+type, obj[type+fn] );
} else
obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
if ( obj.detachEvent ) {
obj.detachEvent( 'on'+type, obj[type+fn] );
obj[type+fn] = null;
} else
obj.removeEventListener( type, fn, false );
}

参考::http://ejohn.org/projects/flexible-javascript-events/

JS-为句柄添加监听函数的更多相关文章

  1. JS通用事件监听函数

    JS通用事件监听函数 版本一 //把它全部封装到一个对象中 var obj={ readyEvent:function (fn){ if(fn==null){ fn=document; } var o ...

  2. Vue.js中 watch(深度监听)的最易懂的解释

    <div> <p>FullName: {{fullName}}</p> <p>FirstName: <input type="text& ...

  3. ExtJs 学习之开篇(二) Observable 给类添加监听

    html:代码 DOCTYPE html><html><head><meta charset="UTF-8"><title>I ...

  4. JS原生 未来元素监听写法

    绑定事件的另一种方法是用 addEventListener() 或 attachEvent() 来绑定事件监听函数. addEventListener()函数语法:elementObject.addE ...

  5. EventTrigger动态添加监听事件

    在 Unity3D 中,通过拖拽的方式在 EventTrigger 组件中添加监听事件就不多说了,很简单.这里主要说的是通过代码动态往 EventTrigger 组件中添加监听事件,有个很坑的地方,就 ...

  6. 移动端用js与jquery实时监听输入框值的改动

    背景: 在一次移动端H5开发中,需要监听输入框值的实时变动. onchange事件肯定抛弃,因为只能失去焦点才触发. 而keyPress在Android可以触发,iOS不可以. 又不想用Android ...

  7. js与jquery实时监听输入框值变化方法

    本文实例讲述了js与jquery实时监听输入框值的oninput与onpropertychange方法.分享给大家供大家参考.具体如下: 最近做过一个项目,需求是下拉框里自动匹配关键字,具体细节是实时 ...

  8. miniui 给表格行添加监听事件的几种方法以及点击某列列名数据不能排序的问题

    最近在使用miniui框架做开发,在做表格行的点击监听事件中发现了几个属性,都可以起到监听效果但是执行的结果却大有不同.好了废话不多说,直接上代码. <div id="pageGrid ...

  9. 11G R2 RAC添加监听

    步骤如下: 检查默认network的network number,红色字体1,一会儿添加监听会用到: [grid@rac121 admin]$ srvctl config network Networ ...

随机推荐

  1. js代码小优化

    今天真坑,老大请了两天假,来了之后指指点点,不过人家说的倒是很是到位 好不容易把嵌套小窗口登陆注册功能,做完了,直接调之前写好的登陆注册功能,也就是页面跳转 并不是ajax异步登陆 说让改成ajax ...

  2. 关于python安全性的问题

    收集总结了一下python安全方面的知识点以及近年来的相关漏洞,如果有需要修正或补充的地方,欢迎各位师傅的指出. 常见web漏洞在python中的示例. xss python下的xss其原理跟php是 ...

  3. HDU4893【线段树单点、区间更新】

    题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=4893] 题意:输入n.q.表示有n个数,初始化默认这n个数都为零,有q次操作,操作种类分为三种:1.输 ...

  4. 【BZOJ 3442】 3442: 学习小组 (最大费用流)

    3442: 学习小组 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 403  Solved: 193 Description [背景] 坑校准备鼓励学生 ...

  5. [APIO / CTSC2007]数据备份 --- 贪心

    [APIO / CTSC 2007]数据备份 题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份. 然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公 ...

  6. [CodeForces-440D]Berland Federalization

    题目大意: 给你一棵树,你可以删掉一些边,使得分除去的子树中至少有一棵大小为k. 问最少删去多少边,以及删边的具体方案. 思路: 树形DP. f[i][j]表示以i为根,子树中去掉j个点最少要删边的数 ...

  7. Codeforces Beta Round #9 (Div. 2 Only) B. Running Student 水题

    B. Running Student 题目连接: http://www.codeforces.com/contest/9/problem/B Description And again a misfo ...

  8. Codeforces Beta Round #5 A. Chat Server's Outgoing Traffic 水题

    A. Chat Server's Outgoing Traffic 题目连接: http://www.codeforces.com/contest/5/problem/A Description Po ...

  9. poj 2528 Mayor's posters 线段树区间更新

    Mayor's posters Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=2528 Descript ...

  10. hihocoder1322 树结构判定(161周)

    hihocoder1322 : 树结构判定(161周) 题目链接 思路: 无向图中判断是不是一棵树. 并查集判断.判断是不是只有一个连通分量.并且该联通分量中没有环.没有环的判定很简单就是看边的数目和 ...