跟我学jquery(六)jquery中事件详解 .

   由于jquery本身就是web客户端的有力帮手,所以事件对于它来说就显得尤为重要了,事件是脚本编程的灵魂所以此内容也是jQuery学习的重点


       在传统的javascript中,注册一个事件也是非常简单的事情,下面我们具体看一下一个简单的示例:

  1. document.getElementById("testDiv2").onclick = showMsg;  

等效于:

  1. <div id="testDiv1" onclick="alert("!!!");">单击事件 1</div>  

注意两者的区别了吗我们常用的修改元素属性添加事件的方式实际上是建立了一个匿名函数:

  1. document.getElementById("testDiv1").onclick = function(event)  
  2. {  
  3.     alert("!!!");  
  4. };  

这个匿名函数的签名和我们手写的showMsg签名相同所以可以把showMsg直接赋值给onclick.

这种方式的弊端是:


1. 只能为一个事件绑定一个事件处理函数使用"="赋值会把前面为此时间绑定的所有事件处理函数冲掉.

2. 在事件函数(无论是匿名函数还是绑定的函数)中获取事件对象的方式在不同浏览器中要特殊处理:

3. 添加多播委托的函数在不同浏览器中是不一样的.


      所以我们首先应该摒弃<div onclick="..."></div>这种通过修改元素属性添加事件的方式尽量使用添加多播事件委托的方式为一个事件绑定多个事件处理函数比如为document对象的单击事件添加一个关闭弹出层的方法使用多播就不会影响document对象原有的事件处理函数.


Jquery事件:

从上面我们看到了javascript中注册事件的弊端了,这些弊端真正避免起来也挺麻烦的,所以jquery想到了这一点,他几乎把javascript中的事件弊端解决到了极点,我们可以很简单的实现我们在javascript中很麻烦才能实现的功能。正所谓有了jQuery, 天天喝茶水下面是在jQuery中最常使用的bind()方法举例:

  1. $("#testDiv").bind("click", showMsg);  

我们为idtestDiv4的元素添加列click事件的事件处理函数showMsg.

使用jQuery事件处理函数的好处:

1. 添加的是多播事件委托也就是为click事件又添加了一个方法不会覆盖对象的click事件原有的事件处理函数.

           

[javascript] view plaincopyprint?
  1. $("#testDiv").bind("click"function(event) { alert("one"); });  
  2.            $("#testDiv").bind("click"function(event) { alert("two"); });  


单击testDiv对象时依次提示"one""two".


2. 统一了事件名称.
添加多播事件委托时, ie中是事件名称前面有"on". 但是使用bind()函数我们不用区分iedom , 因为内部jQuery已经帮我们统一了事件的名称.


3. 可以将对象行为全部用脚本控制.
HTML代码部分只注意"显示"逻辑现在的趋势是将HTML的行为内容与样式切分干净其中用脚本控制元素行为HTML标签控制元素内容CSS控制元素样式使用jQuery事件处理函数可以避免在HTML标签上直接添加事件.


Jquery常用事件函数:

虽然我们可以使用事件处理函数完成对象事件的几乎所有操作但是jQuery提供了对常用事件的封装比如单击事件对应的两个方法click()click(fn)分别用来触发单击事件和设置单击事件.

设置单击事件:

[javascript] view plaincopyprint?
  1. $("#testDiv").click(function(event) { alert("test div clicked ! "); });  
$("#testDiv").click(function(event) { alert("test div clicked ! "); });


等效于:

[javascript] view plaincopyprint?
  1. $("#testDiv").bind("click"function(event) { alert("test div clicked ! "); });  

触发单击事件:

[javascript] view plaincopyprint?
  1. $("#testDiv").click();  

等效于

[javascript] view plaincopyprint?
  1. $("#testDiv").trigger("click");  
$("#testDiv").trigger("click");

注意这里等效的是trigger而不是triggerHandler.

下面我们来看一下这些常用的事件函数

方法

描述

bind()

向匹配元素附加一个或更多事件处理器

blur()

触发、或将函数绑定到指定元素的 blur 事件

change()

触发、或将函数绑定到指定元素的 change 事件

click()

触发、或将函数绑定到指定元素的 click 事件

dblclick()

触发、或将函数绑定到指定元素的 double click 事件

delegate()

向匹配元素的当前或未来的子元素附加一个或多个事件处理器

die()

移除所有通过 live() 函数添加的事件处理程序。

error()

触发、或将函数绑定到指定元素的 error 事件

event.isDefaultPrevented()

返回 event 对象上是否调用了 event.preventDefault()

event.pageX

相对于文档左边缘的鼠标位置。

event.pageY

相对于文档上边缘的鼠标位置。

event.preventDefault()

阻止事件的默认动作。

event.result

包含由被指定事件触发的事件处理器返回的最后一个值。

event.target

触发事件的 DOM 元素。

event.timeStamp

该属性返回从 1970 年 月 日到事件发生时的毫秒数。

event.type

描述事件的类型。

event.which

指示按了哪个键或按钮。

focus()

触发、或将函数绑定到指定元素的 focus 事件

keydown()

触发、或将函数绑定到指定元素的 key down 事件

keypress()

触发、或将函数绑定到指定元素的 key press 事件

keyup()

触发、或将函数绑定到指定元素的 key up 事件

live()

触发、或将函数绑定到指定元素的 load 事件

load()

触发、或将函数绑定到指定元素的 load 事件

mousedown()

触发、或将函数绑定到指定元素的 mouse down 事件

mouseenter()

触发、或将函数绑定到指定元素的 mouse enter 事件

mouseleave()

触发、或将函数绑定到指定元素的 mouse leave 事件

mousemove()

触发、或将函数绑定到指定元素的 mouse move 事件

mouseout()

触发、或将函数绑定到指定元素的 mouse out 事件

mouseover()

触发、或将函数绑定到指定元素的 mouse over 事件

mouseup()

触发、或将函数绑定到指定元素的 mouse up 事件

one()

向匹配元素添加事件处理器。每个元素只能触发一次该处理器。

ready()

文档就绪事件(当 HTML 文档就绪可用时)

resize()

触发、或将函数绑定到指定元素的 resize 事件

scroll()

触发、或将函数绑定到指定元素的 scroll 事件

select()

触发、或将函数绑定到指定元素的 select 事件

submit()

触发、或将函数绑定到指定元素的 submit 事件

toggle()

绑定两个或多个事件处理器函数,当发生轮流的 click 事件时执行。

trigger()

所有匹配元素的指定事件

triggerHandler()

第一个被匹配元素的指定事件

unbind()

从匹配元素移除一个被添加的事件处理器

undelegate()

从匹配元素移除一个被添加的事件处理器,现在或将来

unload()

触发、或将函数绑定到指定元素的 unload 事件


交互帮助方法:


除了基本的实践, jQuery提供了两个和事件相关的帮助方法hover( over, out ) 和 toggle( fn, fn2, fn3,fn4,... )


1. hover( over, out )

hover函数主要解决在原始javascriptmouseovermouseout函数存在的问题看下面这个示例:

有两个div(红色区域), 里面分别嵌套了一个div(黄色区域). HTML代码如下:

    

  1. <div class="outer" id="outer1">  
  2.       Outer 1  
  3.       <div class="inner" id="inner1">Inner 1</div>  
  4.     </div>  
  5.     <div class="outer" id="outer2">  
  6.       Outer 2  
  7.       <div class="inner" id="inner2">Inner 2</div>  
  8.     </div>  
  9.     <div id="console"></div>  

绑定如下事件:

   

[javascript] view plaincopyprint?
  1. <script type="text/javascript">  
  2.      function report(event) {  
  3.        $('#console').append('<div>'+event.type+'</div>');  
  4.      }  
  5.      $(function(){  
  6.        $('#outer1')  
  7.         .bind('mouseover',report)  
  8.         .bind('mouseout',report);  
  9.        $('#outer2').hover(report,report);  
  10.      });  
  11.    </script>  


Outer1我们使用了mouseovermouseout事件当鼠标从Outer1的红色区域移动到黄色区域时会发现虽然都是在outer1的内部移动但是却触发了mouseout事件:

很多时候我们不希望出现上图的结果而是希望只有鼠标在Outer1内部移动时不触发事件, Outer2使用Hover()函数实现了这个效果:

注意这里的事件名称进入叫做"mouseenter", 离开叫做"mouseleave", 而不再使用"mouseover""mouseleave"事件.

有经验的开发人员会立刻想到在制作弹出菜单时经常遇到这个问题为弹出菜单设置了mouseout事件自动关闭但是鼠标在弹出菜单内移动时常常莫名其妙触发mouseout事件让菜单关闭. hover()函数帮助我们很好的解决了这个问题.

2. toggle( fn, fn2, fn3,fn4,... )

toggle函数可以为对象添加click事件绑定函数但是设置每次点击后依次的调用函数。

如果点击了一个匹配的元素,则触发指定的第一个函数,当再次点击同一元素时,则触发指定的第二个函数,如果有更多函数,则再次触发,直到最后一个。随后的每次点击都重复对这几个函数的轮番调用。

可以使用unbind("click")来删除。

下面的示例演示如何使用toggle函数:

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">  
  2. <html>  
  3. <head>  
  4.     <title>toggle example</title>  
  5.     <link rel="stylesheet" type="text/css" href="css/hover.css">  
  6.     <script type="text/javascript" src="scripts/jquery-1.3.2-vsdoc2.js"></script>  
  7.     <script type="text/javascript">  
  8.         $(function()  
  9.         {  
  10.             $("li").toggle(  
  11.               function()  
  12.               {  
  13.                   $(this).css({ "list-style-type": "disc", "color": "blue" });  
  14.               },  
  15.               function()  
  16.               {  
  17.                   $(this).css({ "list-style-type": "square", "color": "red" });  
  18.               },  
  19.               function()  
  20.               {  
  21.                   $(this).css({ "list-style-type": "none", "color": "" });  
  22.               }  
  23.             );  
  24.         })  
  25.     </script>  
  26. </head>  
  27. <body>  
  28.     <ul>  
  29.         <li style="cursor:pointer">click me</li>  
  30.     </ul>  
  31. </body>  
  32. </html>  

结果是每点击一次"click me"变换一次列表符号和文字颜色.


使用jQuery事件对象

使用事件自然少不了事件对象因为不同浏览器之间事件对象的获取以及事件对象的属性都有差异导致我们很难跨浏览器使用事件对象.

jQuery中统一了事件对象当绑定事件处理函数时会将jQuery格式化后的事件对象作为唯一参数传入:

$("#testDiv").bind("click"function(event) {  });


关于event对象的详细说明可以参考jQuery官方文档http://docs.jquery.com/Events/jQuery.Event

jQuery事件对象将不同浏览器的差异进行了合并比如可以在所有浏览器中通过 event.target 属性来获取事件的触发者(IE中使用原生的事件对象需要访问event.srcElement).

下面是jQuery事件对象可以在扩浏览器支持的属性:

属性名称

描述

举例

type

事件类型.如果使用一个事件处理函数来处理多个事件可以使用此属性获得事件类型,比如click.

$("a").click(function(event) {

  alert(event.type);

});

target

获取事件触发者DOM对象

$("a[href=http://google.com]").click(function(event) {

  alert(event.target.href);

});

data

事件调用时传入额外参数.

$("a").each(function(i) {

  $(this).bind('click', {index:i}, function(e){

     alert('my index is ' + e.data.index);

  });

});

relatedTarget

对于鼠标事件标示触发事件时离开或者进入的DOM元素

$("a").mouseout(function(event) {

  alert(event.relatedTarget);

});

currentTarget

冒泡前的当前触发事件的DOM对象等同于this.

$("p").click(function(event) {

  alert( event.currentTarget.nodeName );

});


结果:P

pageX/Y

鼠标事件中事件相对于页面原点的水平/垂直坐标.

$("a").click(function(event) {

  alert("Current mouse position: " + event.pageX + ", " + event.pageY );

});

result

上一个事件处理函数返回的值

$("p").click(function(event) {

  return "hey"

});

$("p").click(function(event) {

  alert( event.result );

});


结果:"hey"

timeStamp

事件发生时的时间戳.

var last;

$("p").click(function(event) {

   if( last )

      alert( "time since last event " + event.timeStamp - last );

   last = event.timeStamp;

});

上面是jQuery官方文档中提供的event对象的属性"jQuery实战"一书中还提供了下面的多浏览器支持的属性时间关系我没有尝试每一个属性大家可以帮忙验证是否在所有浏览器下可用:

属性名称

描述

举例

altKey

Alt键是否被按下按下返回true

ctrlKey

ctrl键是否被按下按下返回true

metaKey

Meta键是否被按下按下返回true.
meta键就是PC机器的Ctrl,或者Mac机器上面的Command

shiftKey

Shift键是否被按下按下返回true

keyCode

对于keyupkeydown事件返回被按下的键不区分大小写, aA都返回65.

对于keypress事件请使用which属性因为which属性跨浏览时依然可靠.

which

对于键盘事件返回触发事件的键的数字编码对于鼠标事件返回鼠标按键号(1,2,3).

screenX/Y

对于鼠标事件获取事件相对于屏幕原点的水平/垂直坐标

事件对象除了拥有属性还拥有事件有一些是一定会用到的事件比如取消冒泡 stopPropagation() .下面是jQuery事件对象的函数列表:

名称

说明

举例

preventDefault()

取消可能引起任何语意操作的事件比如<a>元素的href链接加载表单提交以及click引起复选框的状态切换.

$("a").click(function(event){

  event.preventDefault();

  // do something

});

isDefaultPrevented()

是否调用过 

preventDefault()

方法

$("a").click(function(event){

  alert( event.isDefaultPrevented() );

  event.preventDefault();

  alert( event.isDefaultPrevented() );

});

stopPropagation()

取消事件冒泡

$("p").click(function(event){

  event.stopPropagation();

  // do something

});

isPropagationStopped()

是否调用过 

stopPropagation()

方法

$("p").click(function(event){

  alert( event.isPropagationStopped() );

  event.stopPropagation();

  alert( event.isPropagationStopped() );

});

stopImmediatePropagation()

取消执行其他的事件处理函数并取消事件冒泡.

如果同一个事件绑定了多个事件处理函数在其中一个事件处理函数中调用此方法后将不会继续调用其他的事件处理函数.

$("p").click(function(event){

  event.stopImmediatePropagation();

});

$("p").click(function(event){

  // This function won't be executed

});

isImmediatePropagationStopped()

是否调用过 

stopImmediatePropagation()

方法

$("p").click(function(event){

  alert( event.isImmediatePropagationStopped() );

  event.stopImmediatePropagation();

  alert( event.isImmediatePropagationStopped() );

});


这些函数中 stopPropagation() 是我们最长用的也是一定会用到的函数相当于操作原始event对象的event.cancelBubble=true来取消冒泡.

上一篇:Apeiron公司展示“火箭级”英特尔Optane阵列技术


下一篇:jQuery中的事件绑定