详解jQuery事件
事件是Web应用中不可或缺的一个东西,用户在应用中执行一个操作的时候,比如鼠标单击时要触发执行一些事情,就可以给该事件绑定一个事件处理程序(eventhandler)。使用jQuery的.on()方法可以为选中的元素绑定任意的DOM事件,并添加事件处理程序。假设有如下HTML结构:
<!DOCTYPEhtml> <htmllang="en"> <head> <metacharset="utf-8"> </head> <body> <buttonid="example"type="button">Clickme!</button> <scriptsrc="http://code.jquery.com/jquery-1.11.2.js"></script> <script> //codehere </script> </body> </html>
在<script>元素内添加如下代码,其中,事件名称是.on()方法的第一个参数,事件处理程序的回调函数作为第二个参数:
$('#example').on('click',function(e){ alert('Clicked!'); });
这样当该按钮元素触发鼠标单击(click)事件的时候就会执行绑定的事件处理程序,弹出一个对话框!回调函数的第一个参数e为事件对象,通过该对象可以得到很多事件相关的信息,比如事件类型,事件发生的坐标点等以及一些事件方法。回调函数除了可以像这样使用一个匿名函数,也可以使用一个变量标识的函数引用:
$('#example').on('click',clickHandler);
同时绑定多个事件
另外,jQuery还支持使用空格分隔多个事件名称来同时绑定多个事件,比如mouseentermouseleave,同时给元素绑定鼠标移入和鼠标移出事件。可以通过事件对象的type属性来判断发生的是哪个事件:
$('#example').on('mouseentermouseleave',function(e){ if(e.type==='mouseenter'){ //mouseenter }else{ //mouseleave } });
除了上面这种方法外,还可以传入一个键值对来绑定多个事件:
$('#example').on({ mouseleave:function(){ //mouseleave }, mouseenter:function(){ //mouseenter } });
事件上下文
同时给多个元素绑定事件处理程序的时候可以使用事件执行的上下文来简化代码:
$('li').on('click',function(){ var$this=$(this); $this.addClass('active'); });
上下文关键字this引用的是原生DOM元素,所以如果要使用jQuery的方法需要先包装成jQuery对象。
事件委托
事件会经过一个捕捉和冒泡的过程,为了兼容,jQuery只使用了事件的冒泡,即目标元素触发事件后会逐级冒泡直到顶级元素节点。利用事件的冒泡可以将目标元素的事件处理程序绑定到其祖先元素上统一处理,可以给.on()方法传入一个可选的选择器字符串作为第二个参数:
$(document).on('click','#example',clickHandler);
此时表示将id="example"的元素的鼠标单击事件委托绑定到了document元素上,当目标元素(即id="example"的元素)触发鼠标单击事件的时候,该事件就会冒泡到document元素上,从而触发事件处理程序。使用事件委托的好处是如果页面上有很多列表,每个列表都去绑定一个鼠标单击事件,那么就会有很多事件处理程序,会对性能造成影响。利用事件冒泡的原则,将事件处理程序绑定到目标元素的父元素或者祖先元素上,可以明显地减少事件处理程序的数量,改善性能:
$('ul').on('click','li',clickHandler);
使用事件委托另外一个好处是那些动态添加的<li>元素也会具有事件处理程序。个人比较侵向于将事件都委托到document元素上方便管理,而且也不用等到DOM准备就绪:
$(document) .on('click','selector-1',clickHandler) .on('focusin','selector-2',focusHandler);
在IE8中一些事件比如submit或者change是不会冒泡的,但是jQuery对此做了处理,因此也可以放心使用。像focus和blur事件则推荐使用相应的focusin和focusout事件来代替。对于mouseover和mouseout事件,为了避免事件冒泡造成的不良影响,推荐使用mouseenter和mouseleave来代替。
阻止事件冒泡与默认行为
调用事件对象的.stopPropagation()方法可以阻止事件冒泡:
$('#example').on('click',function(e){ e.stopPropagation(); });
这样当单击事件在该元素上发生的时候就不会冒泡了。jQuery还有另外一个方法.stopImmediatePropagation()调用后事件冒泡被阻止同时该元素上后面绑定的事件处理程序也不会执行了:
$('#example').on('click',function(){ alert('Clicked-1!');//会执行 }).on('click',function(e){ e.stopImmediatePropagation(); }).on('click',function(){ alert('Clicked-2!');//不会执行 });
调用事件对象的.preventDefault()方法可以阻止事件的默认行为:
$('#example').on('click',function(e){ e.preventDefault(); });
在事件处理程序中直接返回false可以同时取消冒泡和阻止默认行为:
$('#example').on('click',function(){ returnfalse; });
相当于同时调用了事件对象上面的.stopPropagation()和.preventDefault()方法。如果没有其它操作,还可以进一步简写为$('#example').on('click',false);。
应用示例,点击按钮显示弹出层,点击文档其它地方隐藏:
$(document) .on('click','#example',popup.show) .on('click',popup.hide);
由于事件冒泡,所以该弹出层并不会显示出来,需要在事件处理程序中阻止事件冒泡:
$(document) .on('click','#example',function(e){ e.stopPropagation(); popup.show(); }).on('click',popup.hide);
获取原生事件对象
事件处理程序中引用的事件对象实际上是经过jQuery包装过的,有时候需要使用浏览器原生的事件对象,要得到浏览器原生的事件对象可以通过事件对象的originalEvent属性获取。例如,使用拖拽事件的时候就会用到原生的事件对象:
$('#example').on('dragstart',function(e){ varoriginalEvent=e.originalEvent; originalEvent.dataTransfer.effectAllowed='move'; originalEvent.dataTransfer.setData('text/plain',$(this).text()); originalEvent.dataTransfer.setData('text/html',$(this).html()); originalEvent.dataTransfer.setDragImage('/images/drag.png',-10,-10); });
传递数据
可以给事件处理程序传入数据,该数据保存在事件对象的data属性中:
$('#example').on('click',1,function(e){ console.log(e.data);//1 });
为了区别事件代理,传递的数据貌似不能是一个直接的字符串,不过可以传入一个对象来代替:
$('#example').on('click',{str:'xxx'},function(e){ console.log(e.data.str);//xxx });
自定义事件
除了浏览器的标准事件,还可以绑定自定义事件的事件处理程序,其中事件名可以使用任意命名:
$('#example').on('sleep',function(){ alert('Sleeping!'); });
标准事件的事件处理程序可以通过浏览器原生事件去触发,而自定义事件的事件处理程序则可以使用jQuery的.trigger()方法触发,使用方式如下,传入需要触发的事件名称作为参数:
$('#example').trigger('sleep');
可以通过给trigger()方法传入更多参数来给事件处理程序传递数据,数据会作为回调函数的参数进行传递:
$('#example').on('sleep',function(e,time){ alert('Sleepat'+time); }); $('#example').trigger('sleep','22:00');
应用示例,使用自定义事件编写异步代码:
$('#example').on('done',doHandler); functionfoo(){ setTimeout(function(){ //foo函数的逻辑比较耗时,所以使用setTimeout函数排队 $('#example').trigger('done');//执行完了,通知一声 },1000); }
foo函数执行完成后,就会触发元素的done事件,前面绑定的doHandler函数就会开始执行。
事件命名空间
无论是浏览器标准事件或是自定义事件都可以添加命名空间,添加在事件名称后面,通过一个.号分隔,像这样click.widget,也可以给一个事件添加多个命名空间click.widget.common,使用命名空间可以更有针对性地触发或者移除某个特定的事件处理程序。比如一个元素同时绑定了click.tab和click.collapse两个点击事件,当使用.trigger()方法触发click.collapse事件时会执行该事件的事件处理程序,而click.tab的事件处理程序则不会执行。
移除绑定事件
使用.off()方法可以移除绑定的事件处理程序,有下面几种情况:
- 不指定任何参数,移除该元素上绑定的所有事件处理程序。
- 指定事件名,如.off('click')表示移除该元素上绑定的所有单击事件处理程序。
- 指定事件处理程序,如.off('click',clickHandler)表示仅移除该事件处理程序(是的,匿名函数不能这样移除)。
- 指定事件命名空间,如.off('.widget')表示移除该命名空间下所有的事件处理程序(比如绑定的click.widget和change.widget事件处理程序都会被移除),该方式可以用于移除某个组件绑定的各种事件。
- 指定事件代理的元素,如$(document).off('click','#example'),可以移除为该元素绑定的事件代理处理程序。
一次性事件
使用.one()方法绑定的事件处理程序只会触发执行一次,一次后自动移除:
$('#example').one('click',clickHandler);
事件节流
浏览器中有几个事件会频繁触发,比如scroll,resize,mousemove等,那么给这些事件绑定的事件处理程序也会跟着频繁地执行,导致页面反应迟钝,要解决这个问题,需要节流事件,减少事件处理程序执行的频率:
vartimer=0;//使用一个定时器 $(window).on('scroll',function(){ if(!timer){ timer=setTimeout(function(){ //Dosomething timer=0; },200); } });
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持毛票票!