具体谈如何实现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. Shiro切入Spring的方式

    在springMVC中要使用shiro,一般都遵循下面的配置: applicationContext-shiro.xml <bean id="shiroFilter" cla ...

  2. 批量 添加 安卓构建 版本 eclipse

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha

  3. bzoj1093 [ZJOI2007]最大半联通子图 缩点 + 拓扑序

    最大半联通子图对应缩点后的$DAG$上的最长链 复杂度$O(n + m)$ #include <cstdio> #include <cstring> #include < ...

  4. 【DP】BZOJ1592-[Usaco2008 Feb]Making the Grade 路面修整

    我活着从期中考试回来了!!!!!!!!!备考NOIP!!!!!!!!! [题目大意] 给出n个整数a1~an,修改一个数的代价为修改前后差的绝对值,问修改成不下降序列或者不上升序列的最小总代价. [思 ...

  5. 20162327WJH Android开发程序设计实验报告

    学号 20162327 <程序设计与数据结结构>Android开发程序设计实验报告 实验一:Android Stuidio的安装测试: 参考<Java和Android开发学习指南(第 ...

  6. poj 1485 dp

    转自:http://www.cnblogs.com/kuangbin/archive/2011/11/12/2246407.html [题目大意] 一条公路上有n个旅馆,选出其中k个设置仓库,一个仓库 ...

  7. 为什么java的构造方法中this()或者super()要放在第一行

    java的构造方法中如果自己显性的调用super()的时候一定要放在第一行,如不是的话就会报错. 为什么一定要在第一行? super()在第一行的原因就是: 子类有可能访问了父类对象, 比如在构造函数 ...

  8. MongoDB基础学习(一) MongoDB概念解析

    .基础概念 SQL术语/概念 MongoDB术语/概念 说明 database database 数据库 table collection 数据表/集合 row document 数据记录行/文档 c ...

  9. BFC与hasLayout

    BFC与hasLayout都是CSS布局上的概念. 几个月前在微博上才了解什么是BFC,算是对布局有点初步的了解. hasLayout则是IE6.7产生许多bug的根源. 一.BFC Floats, ...

  10. js判断移动设备

    在开发中可能需要去判断用户的设备重定向到相应的网址: 1. 判断 iPhone  Android  iPod if((navigator.userAgent.match(/iPhone/i))||(n ...