事件是脚本编程的灵魂. 因此本章内容也是jQuery学习的重点. 本文将对jQuery中的事件处理以及事件对象进行详细的讲解. javascript
首先看一下咱们常用的添加事件的方式:css
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>javascript中的事件</title> <script type="text/javascript" src="scripts/jquery-1.3.2-vsdoc2.js"></script> <script type="text/javascript"> $(function() { document.getElementById("testDiv2").onclick = showMsg; }) function showMsg(event) { alert("!!!"); } </script> </head> <body> <div id="testDiv1" onclick="showMsg();">单击事件 1</div> <div id="testDiv2">单击事件 2</div> </body> </html>
咱们最常使用为元素添加onclick元素属性的方式添加事件.html
为testDiv2的添加onclick事件的方式是修改Dom属性.java
在上一章中已经说明了什么是元素属性, 什么是Dom属性.这两种方式的效果相同. 当单击div时会显示提示框.jquery
请注意, 虽然效果相同, 可是并不等效.编程
document.getElementById("testDiv2").onclick = showMsg;
等效于:浏览器
<div id="testDiv1" onclick="alert("!!!");">单击事件 1</div>
注意二者的区别了吗? 咱们经常使用的修改元素属性添加事件的方式, 其实是创建了一个匿名函数:dom
document.getElementById("testDiv1").onclick = function(event) { alert("!!!"); };
这个匿名函数的签名和咱们手写的showMsg签名相同, 因此能够把showMsg直接赋值给onclick.ide
这个匿名函数的签名和咱们手写的showMsg签名相同, 因此能够把showMsg直接赋值给onclick.函数
这种方式的弊端是:
1. 只能为一个事件绑定一个事件处理函数. 使用"="赋值会把前面为此时间绑定的全部事件处理函数冲掉.
2. 在事件函数(不管是匿名函数仍是绑定的函数)中获取事件对象的方式在不一样浏览器中要特殊处理:
IE中,事件对象是window对象的一个属性.事件处理函数必须这样访问事件对象:
obj.onclick=function() { var oEvent = window.event; }
在DOM标准中,事件对象必须做为惟一参数传给事件处理函数:
obj.onclick=function() { var oEvent = arguments[0]; }
除了使用argument[0]访问此参数, 咱们也能够指定参数名称,上面的代码等同于:
obj.onclick=function(oEvent) { }
目前兼容DOM的浏览器有Firefox,Safari,Opera,IE7等.
3. 添加多播委托的函数在不一样浏览器中是不同的.
下面是在"Javascript公共脚本库系列(二): 添加事件多播委托的方法"文章中, 提供的兼容多浏览器添加多播委托的方法:
//统一的为对象添加多播事件委托的方法 /* 参数说明: oTarget : 要添加事件的对象.好比"document". sEventType : 事件类型.好比单击事件"click". fnHandler : 发生事件时调用的方法. 好比一个静态函数"hideCalendar" 使用举例: //单击页面的任何元素,只要没有取消冒泡,均可以关闭日历控件 var cf = document.getElementById("CalFrame"); if( cf != null && hideCalendar != null ) { ScriptHelper.addEventListener( document, "click", hideCalendar ); } */ scriptHelper.prototype.addEventListener = function(oTarget, sEventType, fnHandler) { if( oTarget.addEventListener )//for dom { oTarget.addEventListener( sEventType, fnHandler, false ) } else if( oTarget.attachEvent )//for ie { oTarget.attachEvent( "on" + sEventType, fnHandler); } }
因此咱们首先应该摒弃<div onclick="..."></div>这种经过修改元素属性添加事件的方式. 尽可能使用添加多播事件委托的方式为一个事件绑定多个事件处理函数, 好比为document对象的单击事件添加一个关闭弹出层的方法, 使用多播就不会影响document对象原有的事件处理函数.
有了jQuery, 咱们有了处理对象事件的一系列函数. 上面基础知识仍是要懂, 可是不再用本身去实现处理多播事件委托的函数了. 正所谓有了jQuery, 每天喝茶水. 下面是在jQuery中最常使用的bind()方法举例:
$("#testDiv4").bind("click", showMsg);
咱们为id是testDiv4的元素, 添加列click事件的事件处理函数showMsg.
使用jQuery事件处理函数的好处:
1. 添加的是多播事件委托. 也就是为click事件又添加了一个方法, 不会覆盖对象的click事件原有的事件处理函数.
$("#testDiv4").bind("click", function(event) { alert("one"); }); $("#testDiv4").bind("click", function(event) { alert("two"); });
单击testDiv4对象时, 依次提示"one"和"two".
2. 统一了事件名称.
添加多播事件委托时, ie中是事件名称前面有"on". 可是使用bind()函数咱们不用区分ie和dom , 由于内部jQuery已经帮咱们统一了事件的名称.
3. 能够将对象行为所有用脚本控制.
让HTML代码部分只注意"显示"逻辑. 如今的趋势是将HTML的行为, 内容与样式切分干净. 其中用脚本控制元素行为, 用HTML标签控制元素内容, 用CSS控制元素样式. 使用jQuery事件处理函数能够避免在HTML标签上直接添加事件.
bind()是最常使用的函数, 注意方法签名上data参数, 能够在事件处理以前传递一些附加的数据:
function handler(event) { alert(event.data.foo); } $("p").bind("click", {foo: "bar"}, handler)
注意event参数的使用. jQuery中统一了事件对象, 将事件对象做为事件处理函数的惟一参数传递.
data参数咱们也要经过event.data 进行访问. 为什么要提供data参数呢?
由于咱们常常碰到这样的问题: 但愿在事件处理中根据事件源的某些数据进行特殊处理.
目前网上有两种存在争议的解决方法:
(1) 使用自定义元素属性存储数据.
好比:
<div id="testDiv5" customer="customer data 1">获取自定义数据-1</div>
在事件处理函数中获取数据:
$("#testDiv5").bind("click", function(event) { alert($(event.target).attr("customer")); });
attr函数是上一讲中的知识, 用于获取元素的"元素属性", 并且能够获取自定义的元素属性. 单击div后将显示:
(2) 使用脚本将数据传递给事件处理函数:
<div id="testDiv6">获取自定义数据-2</div>
元素没有任何的自定义属性, 添加事件处理函数时将额外的数据传递:
$("#testDiv6").bind("click", { customer: "customer data 2" }, function(event) { alert(event.data.customer) });
点击div后的结果和方法1相同:
方法1便于存储和查找数据. 可是自定义属性经过不W3C验证.
方法2必需要本身想办法存储数据, 而且要制定规则查找指定元素的数据.
从"开发人员"的角度方法1要更加简单直观. 可是缺点比较严重. 因此如何取舍请你们本身决定.
one( type, [data], fn ) 函数和bind同样, 可是只执行一次.
虽然为元素绑定了某些事件, 好比click, 可是有时但愿在程序中触发这些事件, 这两个函数能够实现此功能.
主要区别是trigger会出发浏览器默认的动做, 而triggerHandler不会出发.
经过下面的实例能够明确的区分这两个函数:
BUG提示:jquery-1.3.2-vsdoc2.js 这个最新的官方带智能提示的类库, 没法使用快捷事件, 好比click(), focus(). 使用其余版本的类库则没有问题.
虽然咱们可使用事件处理函数完成对象事件的几乎全部操做, 可是jQuery提供了对经常使用事件的封装. 好比单击事件对应的两个方法click()和click(fn)分别用来触发单击事件和设置单击事件.
设置单击事件:
$("#testDiv").click(function(event) { alert("test div clicked ! "); });
等效于:
$("#testDiv").bind("click", function(event) { alert("test div clicked ! "); });
触发单击事件:
$("#testDiv").click();
等效于
$("#testDiv").trigger("click");
除了基本的实践, jQuery提供了两个和事件相关的帮助方法: hover( over, out ) 和 toggle( fn, fn2, fn3,fn4,... )
hover函数主要解决在原始javascript中mouseover和mouseout函数存在的问题
toggle函数能够为对象添加click事件绑定函数, 可是设置每次点击后依次的调用函数。
若是点击了一个匹配的元素,则触发指定的第一个函数,当再次点击同一元素时,则触发指定的第二个函数,若是有更多函数,则再次触发,直到最后一个。随后的每次点击都重复对这几个函数的轮番调用。
可使用unbind("click")来删除。
下面的示例演示如何使用toggle函数:
<html> <head> <title>toggle example</title> <link rel="stylesheet" type="text/css" href="css/hover.css"> <script type="text/javascript" src="scripts/jquery-1.3.2-vsdoc2.js"></script> <script type="text/javascript"> $(function() { $("li").toggle( function() { $(this).css({ "list-style-type": "disc", "color": "blue" }); }, function() { $(this).css({ "list-style-type": "square", "color": "red" }); }, function() { $(this).css({ "list-style-type": "none", "color": "" }); } ); }) </script> </head> <body> <ul> <li style="cursor:pointer">click me</li> </ul> </body> </html>
使用事件天然少不了事件对象. 由于不一样浏览器之间事件对象的获取, 以及事件对象的属性都有差别, 致使咱们很难跨浏览器使用事件对象.
jQuery中统一了事件对象, 当绑定事件处理函数时, 会将jQuery格式化后的事件对象做为惟一参数传入:
$("#testDiv").bind("click", function(event) { });
关于event对象的详细说明, 能够参考jQuery官方文档: http://docs.jquery.com/Events/jQuery.Event
jQuery事件对象将不一样浏览器的差别进行了合并, 好比能够在全部浏览器中经过 event.target 属性来获取事件的触发者(在IE中使用原生的事件对象, 须要访问event.srcElement).
事件是javascript的灵魂,