简单讨论一下 jQuery 事件
事件是 Web 应用中不可或缺的一个东西,用户在应用中执行一个操作的时候,比如鼠标单击时要触发执行一些事情,就可以给该事件绑定一个事件处理程序(event handler)。使用 jQuery 的 .on() 方法可以为选中的元素绑定任意的 DOM 事件,并添加事件处理程序。假设有如下 HTML 结构:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<button id="example" type="button">Click me!</button>
<script src="http://code.jquery.com/jquery-1.11.2.js"></script>
<script>
// code here
</script>
</body>
</html>
在 <script> 元素内添加如下代码,其中,事件名称是 .on() 方法的第一个参数,事件处理程序的回调函数作为第二个参数:
$('#example').on('click', function(e) {
alert('Clicked!');
});
这样当该按钮元素触发鼠标单击(click)事件的时候就会执行绑定的事件处理程序,弹出一个对话框!回调函数的第一个参数 e 为事件对象,通过该对象可以得到很多事件相关的信息,比如事件类型,事件发生的坐标点等以及一些事件方法。回调函数除了可以像这样使用一个匿名函数,也可以使用一个变量标识的函数引用:
$('#example').on('click', clickHandler);
同时绑定多个事件
另外,jQuery 还支持使用空格分隔多个事件名称来同时绑定多个事件,比如 mouseenter mouseleave,同时给元素绑定鼠标移入和鼠标移出事件。可以通过事件对象的 type 属性来判断发生的是哪个事件:
$('#example').on('mouseenter mouseleave', 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() {
return false;
});
相当于同时调用了事件对象上面的 .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) {
var originalEvent = 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('Sleep at' + time);
});
$('#example').trigger('sleep', '22:00');
应用示例,使用自定义事件编写异步代码:
$('#example').on('done', doHandler);
function foo() {
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 等,那么给这些事件绑定的事件处理程序也会跟着频繁地执行,导致页面反应迟钝,要解决这个问题,需要节流事件,减少事件处理程序执行的频率:
var timer = 0; // 使用一个定时器
$(window).on('scroll', function() {
if (!timer) {
timer = setTimeout(function() {
// Do something
timer = 0;
}, 200);
}
});
简单讨论一下 jQuery 事件的更多相关文章
- 第79天:jQuery事件总结(二)
上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件.事件冒泡和事件移除等内容. 一.合成事件 jQuery有两个合成事件——hove ...
- 阻止jQuery事件冒泡
Query对DOM的事件触发具有冒泡特性.有时利用这一特性可以减少重复代码,但有时候我们又不希望事件冒泡.这个时候就要阻止 jQuery.Event冒泡. 在jQuery.Event 的文档 中的开头 ...
- jQuery事件绑定和委托实例
本文实例讲述了jQuery事件绑定和委托.分享给大家供大家参考.具体方法如下: jQuery事件的绑定和委托可以用多种方法实现,on() . bind() . live() . delegate ...
- jquery事件核心源码分析
我们从绑定事件开始,一步步往下看: 以jquery.1.8.3为例,平时通过jquery绑定事件最常用的是on方法,大概分为下面3种类型: $(target).on('click',function( ...
- 解密jQuery事件核心 - 委托设计(二)
第一篇 http://www.cnblogs.com/aaronjs/p/3444874.html 从上章就能得出几个信息: 事件信息都存储在数据缓存中 对于没有特殊事件特有监听方法和普通事件都用ad ...
- 解密jQuery事件核心 - 模拟事件(四)
前几章已经把最核心的实现都分解过了,这一章我们看看jQuery是如何实现事件模拟的 在Internet Explorer 8和更低,一些事件change 和 submit本身不冒泡,但jQuery修改 ...
- 深入学习jQuery事件绑定
× 目录 [1]bind [2]trigger [3]delegate[4]on[5]one 前面的话 javascript有HTML.DOM0级.DOM2级和IE这四种事件处理程序,而jQuery对 ...
- jQuery 事件用法详解
jQuery 事件用法详解 目录 简介 实现原理 事件操作 绑定事件 解除事件 触发事件 事件委托 事件操作进阶 阻止默认事件 阻止事件传播 阻止事件向后执行 命名空间 自定义事件 事件队列 jque ...
- asp.net中ScriptManager自带Ajax与jQuery事件冲突
问题引诉:最近在使用asp.net自带的无刷新提交ScriptManager时,发现一个问题,就是和我自己用jQuery写的一些事件函数和局部刷新相冲突.通过在网上收索,发现很多人都遇到这个同样的问题 ...
随机推荐
- 机器学习学习-Types of learning
Types of learning 基于个人理解.于我们在面对一个详细的问题时.可以依据要达到的目标选择合适的机器学习算法来得到想要的结果.比方,推断一封电子邮件是否是垃圾邮件,就要使用分类(clas ...
- 在ubuntu下使用eclipse来调试ARM程序
该程序为外部Makefile project,导入到eclipse中来进行编译,之后使用Jlink来进行调试. 这个是因为你在编译的时候没有加-g这个标志,导致没有生成调试文件. 让你指定一个源文件. ...
- Floodlight 启动过程分析
1. 在Main中先是载入模块,启动REST服务,而后构建一个实现了IFloodlightProviderService接口的实例(即Controller)并执行: 2. 接下来进入Control ...
- 分享12款经典时尚的HTML5应用
分享伟大,呵呵.今天给大家分享一下收集的12个HTML5小特效. 我整理一下源码,给大家打包一下,我博客园上传文件大小有限,传不了了. 需要的请留下邮箱就行了,觉得好的话,不要忘了点赞哦~ 1.CSS ...
- 【SSRS】入门篇(五) -- 设置报表格式
原文:[SSRS]入门篇(五) -- 设置报表格式 在上一节 [SSRS]入门篇(四) -- 向报表添加数据 我们设置好了报表,并可以预览到数据,如下图: 当报表完成后,有个重要的工作就是美化报表格式 ...
- Lamda Action Func Thread 实例
lamda表达式 格式:( 形参列表 ) => { 函数体 } 作用:简化匿名方法的书写,可用在任何可使用匿名方法和强类型代理的地方: Action是无返回值的泛型委托. Action 表示无参 ...
- Visual Studio 2013中的“Browser Link”
前几天,参加了,VS13的新特性的讲座,回来便试了一下, 默认Html会引用如下脚本: <!-- Visual Studio Browser Link --> <script typ ...
- 今天用C#做的一个小的注册练习
下边是实现的代码: using System;using System.Collections.Generic;using System.ComponentModel;using System.Dat ...
- 重定向和VT100编程
重定向和VT100编程 一.文件重定向 我们知道在linux shell 编程的时候,可以使用文件重定向功能,如下所示: [root@localhost pipe]# echo "h ...
- vj1011:记忆化搜索
vj1011:记忆化搜索 这题就是很简单的记忆化搜索即可,和经典题目滑雪简直一模一样 对于记忆化搜索,我也是暑假看了ccy大神的题解才有所领悟的 其实也就是DFS+mark 主要的部分 int sea ...