Javascript事件绑定的几种方式

来源:http://www.cnblogs.com/rainman/archive/2009/02/11/1387955.html

上篇文章讲到了事件绑定的3中常用方法:传统绑定、W3C绑定方法、IE绑定方法。但是,在实际开发中对于我们来讲重要的是需要一个通用的、跨浏览器的绑定方法。如果我们在互联网上搜索一下会发现许多方法,一下是比较知名的几种方法:

在开始学期下面几种方法之前,应当讨论一下,一个好的addEvent()方法应当达到哪些要求:

   a、支持同一元素的同一事件句柄可以绑定多个监听函数;

   b、如果在同一元素的同一事件句柄上多次注册同一函数,那么第一次注册后的所有注册都被忽略;

   c、函数体内的this指向的应当是正在处理事件的节点(如当前正在运行事件句柄的节点);

   d、监听函数的执行顺序应当是按照绑定的顺序执行;

   e、在函数体内不用使用 event = event || window.event; 来标准化Event对象;

一、John Resig 所写的 addEvent() 函数:http://ejohn.org/projects/flexible-javascript-events/

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] );} elseobj.addEventListener( type, fn, false );}function removeEvent( obj, type, fn ) {if ( obj.detachEvent ) {obj.detachEvent( 'on'+type, obj[type+fn] );obj[type+fn] = null;} elseobj.removeEventListener( type, fn, false );}

这个函数如此简单易懂,的确非常令人惊讶。那么我们还是要看看上面的五点要求:

   对于第一点满足了;

   对于第三点和第五点,肯定也满足了;

   对于第二点,并没有满足,因为addEventListener()会忽略重复注册,而attachEvent()则不会忽略;

   但是第四点,并没有满足,因为Dom标准没有确定调用一个对象的时间处理函数的顺序,所以不应该想当然的认为它们以注册的顺序调用。

但是这个函数仍然是一个非常优秀的函数。

二、Dean Edward 所写的 addEvent() 函数 :http://dean.edwards.name/weblog/2005/10/add-event2/

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;
};

该函数使用了传统的绑定方法,所以它可以在所有的浏览器中工作,也不会造成内存泄露。

但是对于最初提出的5点,该函数只是满足了前四点。只有最后一点没有满足,因为在JavaScript中对for/in语句的执行顺序没有规定是按照赋值的顺序执行,尽管大部分时刻是按照预期的顺序执行,因此在不同的JavaScript版本或实现中这一语句的顺序有可能不同。

三、Dean Edward 的 addEvent() 函数的改进

Array.prototype.indexOf = function( obj ){var result = -1 , length = this.length , i=length - 1;for ( ; i>=0 ; i-- ) {if ( this[i] == obj ) {result = i;break;}}return result;
}
Array.prototype.contains = function( obj ) {return ( this.indexOf( obj ) >=0 )
}
Array.prototype.append = function( obj , nodup ) {if ( !(nodup && this.contains( obj )) ) {this[this.length] = obj;}
}
Array.prototype.remove = function( obj ) {var index = this.indexOf( obj );if ( !index ) return ;return this.splice( index , 1);
};
function addEvent(element , type , fun){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.append( fun , true)element['on' + type] = handleEvent;
}
function removeEvent(element , type , fun) {if (element.events && element.events[type]) {element.events[type].remove(fun); }
}
function handleEvent(event) {var returnValue = true , i=0;event = event || fixEvent(window.event);var handlers = this.events[event.type] , length = handlers.length;for ( ; i < length ; i++) {if ( handlers[i].call( this , 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;
};

该函数是本人对Dean Edward 的 addEvent() 函数的改进,完全满足了最初提出的5点要求。如果大家有更好的方法,期待分享!

来源:http://blog.csdn.net/haijiaoxiaowu/article/details/5150389

Javascript的事件绑定主要有四种方法(一下在IE中运行正常,但不保证其他浏览器):

[注:onXXX为某一事件,fun为某一function,domId为某一DOM对象id,event类型见后边附录。]

1、在DOM中,直接用onXXX="fun();"进行绑定

2、在Javascript代码中用 DOM对象.onXXX=fun 进行绑定

3、用 DOM对象.attachEvent("onXXX",fun) 进行绑定

4、用<script for="domId" event="onXXX">fun();</script> 进行绑定

<html>
<head>
<title>event test</title>
</head>
<body οnlοad="init()">
<!-- 绑定方式一:在元素中,通过onXXX(事件)设置绑定方法 -->
<button id="btn1" οnclick="display()" >绑定方式一</button><!-- 绑定方式二:在Javascript代码中,通过获得元素,为元素的onXXX(事件)设置绑定方法  -->
<button id="btn2">绑定方式二</button><!-- 绑定方式三:通过for、event为元素绑定事件(IE4+)。for后面是元素id,event是具体事件  -->
<button id="btn3">绑定方式三</button><!-- 绑定方式四:通过attachEvent为元素绑定事件(IE5+)。第一个参数是事件名,第二个参数是绑定的方法 -->
<button id="btn4">绑定方式四</button>
</body>
</html>
<script type="text/javascript">function init() {document.getElementById("btn2").onclick = display;//为button2绑定事件document.getElementById("btn4").attachEvent("onclick", display);//为button4绑定事件}function display(event) {var targ;//触发事件的对象引用if (!event) {var event = window.event;//获得当前事件(IE)}if (event.target) {//IE没有targettarg = evente.target;} else if (event.srcElement) {//适用于IEtarg = event.srcElement;}//对触发事件的对象进行操作alert(targ.tagName+"-"+targ.id+"-"+event.x+"-"+event.offsetX);targ.disabled="disabled" ;}
<script>
<script for="btn3" event="onclick">display();//为button3绑定事件
<script>

附一:event事件:

onabort: 图像的加载被中断
onblur: 元素失去焦点
onchange: 域的内容被改变
onclick: 当用户点击某个对象时调用的事件句柄
ondblclick: 当用户双击某个对象时调用的事件句柄
onerror: 在加载文档或图像时发生错误
onfocus: 元素获得焦点
onkeydown: 某个键盘按键被按下
onkeypress: 某个键盘按键被按下并松开
onkeyup: 某个键盘按键被松开
onload: 一张页面或一幅图像完成加载
onmousedown: 鼠标按钮被按下
onmousemove: 鼠标被移动
onmouseout: 鼠标从某元素移开
onmouseover: 鼠标移到某元素之上
onmouseup: 鼠标按键被松开
onreset: 重置按钮被点击
onresize: 窗口或框架被重新调整大小
onselect: 文本被选中
onsubmit: 确认按钮被点击
onunload: 用户退出页面

附二:IE event属性:

cancelBubble: 如果事件句柄想阻止事件传播到包容对象,必须把该属性设为 true。 
fromElement :对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素。 
keyCode :对于 keypress 事件,该属性声明了被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup 事件,它指定了被敲击的键的虚拟键盘码。虚拟键盘码可能和使用的键盘的布局相关。 
offsetX,offsetY :发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标。 
returnValue: 如果设置了该属性,它的值比事件句柄的返回值优先级高。把这个属性设置为 fasle,可以取消发生事件的源元素的默认动作。 
srcElement :对于生成事件的 Window 对象、Document 对象或 Element 对象的引用。 
toElement: 对于 mouseover 和 mouseout 事件,该属性引用移入鼠标的元素。 
x,y: 事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素。

Javascript事件绑定的几种方式相关推荐

  1. JavaScript事件处理程序的3种方式

    最近这段时间因为每天要修改网站,为网站做特效,所以看了很多的js接触事件,自己只会使用一小部分,有时用的时候也比较混乱,现在系统的整理了一下,首先跟大家在马海祥博客上跟大家分享的是JavaScript ...

  2. 原生JS事件绑定的三种方式

    JavaScript绑定事件的方法 要想让 JavaScript 对用户的操作作出响应,首先要对 DOM 元素绑定"事件处理函数".所谓事件处理函数,就是处理用户操作的函数,不同的 ...

  3. JS事件绑定的几种方式

    一.有几种常用的: 在JavaScript中,有三种常用的绑定事件的方法: 1.在DOM元素中直接绑定. 2.在JavaScript代码中绑定. 3.绑定事件监听函数. 二.具体分析: 1.在DOM元 ...

  4. js中事件绑定的几种方式

    事件处理程序即给元素绑定事件的方式有下列几种:HTML事件处理程序.DOM0级事件处理程序.DOM2级事件处理程序.IE事件处理程序.跨浏览器事件处理程序.其实这些方式就是一个逐步优化和实现跨浏览器的 ...

  5. JS 事件绑定的几种方式 小笔记

    第一种 var test=document.getElementById('add'); add.οnclick=function(){ alert('1'); } 直接在对象上注册事件 缺点:如果我 ...

  6. addeventlistener事件第三个参数_简析JavaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序...

    这篇文章主要介绍了javaScript 事件绑定.事件冒泡.事件捕获和事件执行顺序整理总结的相关资料 (一)事件绑定的几种方式 javascript给DOM绑定事件处理函数总的来说有2种方式:在htm ...

  7. 简析JavaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序

    JavaScript 事件绑定.事件冒泡.事件捕获和事件执行顺序 这篇文章主要介绍了javaScript 事件绑定.事件冒泡.事件捕获和事件执行顺序整理总结的相关资料 (一)事件绑定的几种方式 jav ...

  8. 为元素绑定多个相同事件 绑定事件的另一种方式 复习 介绍 元素的事件绑定

    为元素绑定多个相同事件 <!DOCTYPE html> <html lang="en"> <head><meta charset=&quo ...

  9. JavaScript事件绑定的方法说明 收藏

    JavaScript事件绑定的方法说明 收藏 事件使得客户端的 JavaScript 有机会被激活,并得以运行.在一个 Web 页面装载之后,运行脚本的唯一方式,就是响应系统或者用户的动作.虽然从第一 ...

最新文章

  1. linux终端中运行网银盾,Linux下使用Virtualbox安装 Windows 7 操作网银攻略
  2. 为什么在CSDN中同时打开两个Markdown编辑窗口会相互干扰?
  3. mysql使索引失效语句_会导致索引失效语句
  4. 【Leetcode】大神总结的链表常见面试问题
  5. 【笔记】基于边缘检测和BP神经网络的大豆杂草识别研究
  6. 求虚拟机11.0密钥
  7. mybatis 控制台打印执行的SQL语句
  8. 基于JAVA+SpringMVC+Mybatis+MYSQL的物流管理系统
  9. Composite UI Application Block(CAB)
  10. 关于vs08生成解决方案慢的解决方法
  11. easyui+ztree 后台管理系统模板
  12. 配置阿里云maven仓库地址
  13. Python爬取必应壁纸
  14. 你清楚搭建会员积分系统的目的吗?
  15. iPhone删除的照片能恢复吗?苹果手机照片怎么恢复
  16. 关于PHP程序员技术职业生涯规划 2017年3月5日韩 天峰
  17. 分布式系统生成唯一主键
  18. java排他_Activiti之排他网关
  19. 新手站长:成功申请Godaddy域名退款到支付宝全过程
  20. 「法拉第的故事」读后心得

热门文章

  1. 113种渗透测试工具合集(全网最全)
  2. js中常见的Json解析
  3. 《统计学》第八版贾俊平 思维导图
  4. Android 12系统源码_SystemUI(八)SystemUIVisibility属性
  5. linux 查看mapper 路径,Linux系统/dev/mapper目录
  6. visio2010 去除跨线
  7. 微信小程序 自定义组件之 胶囊对齐 搜索FloatSearch
  8. svn 认证失败请看解决办法
  9. 网络协议——七层、五层、四层协议概念
  10. windows10安装redis数据库,并设置开机自启动