jQuery代码优化:基本事件
jQuery对事件系统的抽象与优化也是它的一大特色。本文仅从事件系统入手,简要分析一下jQuery为什么提供mouseenter和mouseleave事件,它们与标准的mouseover、mouseout事件有什么区别。
事件模型
说到事件,就要追溯到网景与微软的“浏览器大战”了。当时,事件模型还没有标准,两家公司的实现就是事实标准。网景在Navigator中实现了 “事件捕获”的事件系统,而微软则在IE中实现了一个基本上相反的事件系统,叫做“事件冒泡”。这两种系统的区别在于当事件发生时,相关元素处理(响应) 事件的优先权不同。
下面举例说明这两种事件机制的区别。假设文档中有如下结构:
1
2
3
4
5
|
< div > < span > < a >...</ a > </ span > </ div > |
因为这三个元素是嵌套的,所以单击了a,实际上也就单击了span和div。换句话说,这三个元素都应该有处理单击事件的机会。在事件捕获机制下, 处理这个单击事件的优先次序是:div > span > a;而在事件冒泡机制下,处理这个单击事件的优先次序则是:a > span > div。
后来,W3C的规范要求浏览器同时支持捕获和冒泡机制,并允许开发人员选择把事件注册到哪个阶段。于是就有了下面这个注册事件的标准方法:
1
|
target.addEventListener(type, listener, useCapture Optional ); |
其中:
- type:字符串,表示监听的事件类型
- listener:监听器对象(JavaScript函数),在指定事件发生时可以收到通知
- useCapture:布尔值,是否注册到捕获阶段
在实际应用开发中,为了确保与IE(因为它不支持捕获)兼容,useCapture一般都指定为false(默认值也是false)。换句话说,只把事件注册到冒泡阶段;对于上面那个简单的例子来说,响应顺序就是:a > span > div。
冒泡的副作用
如前所述,IE的冒泡事件模型基本上成为了事实标准。但冒泡有一个副作用。
仍以前面的文档结构为例,假设它是界面中的一个菜单项,我们希望用户鼠标离开div时隐藏菜单。于是,我们给div注册了一个mouseout事 件。如果用户鼠标是从div离开的,那么一切正确。而如果用户鼠标是从a或span离开的,问题就来了。因为由于事件冒泡,从这两个元素开始分派的 mouseout事件都会传播到div,从而导致鼠标并没有离开div,菜单就提前隐藏了。
当然,冒泡的副作用不难避免。比如,给div内部的每个元素都注册mouseout事件,并使用.stopPropagation()方法阻止事件 进一步传播。对于IE,就得将事件对象的cancelBubble属性设置为false,取消事件冒泡。不过,这仍然回到自己处理浏览器不兼容性问题的老 路上了。
优化方案
为了避免冒泡的副作用,jQuery提供了mouseenter和mouseleave事件,就使用它们来代替mouseover和mouseout吧。
下面这个摘自jQuery的内部函数withinElement,就是为mouseenter和mouseleave提供支持的。翻译了一下注释,仅供大家参考。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
// 下面这个函数用于检测事件是否发生在另一个元素的内部 // 在 jQuery.event.special.mouseenter 和 mouseleave 处理程序中使用 var withinElement = function ( event ) { // 检测 mouse(over|out) 是否还在相同的父元素内 var parent = event.relatedTarget; // 设置正确的事件类型 event.type = event.data; // Firefox 有时候会把 relatedTarget 指定一个 XUL 元素 // 对于这种元素,无法访问其 parentNode 属性 try { // Chrome 也类似,虽然可以访问 parentNode 属性 // 但结果却是 null if ( parent && parent !== document && !parent.parentNode ) { return ; } // 沿 DOM 树向上 while ( parent && parent !== this ) { parent = parent.parentNode; } if ( parent !== this ) { // 如果实际正好位于一个非子元素上面,那好,就处理事件 jQuery.event.handle.apply( this , arguments ); } // 假定已经离开了元素,因为很可能鼠标放在了一个XUL元素上 } catch (e) { } }, |
结论
在jQuery里,可以使用mouseenter和mouseleave事件来避免事件冒泡的副作用。
jQuery代码优化:基本事件的更多相关文章
- jQuery代码优化的9种方法
前面的话 本文将详细介绍jQuery代码优化的9种方法 用对选择器 在jQuery中,可以用多种选择器,选择同一个网页元素.每种选择器的性能是不一样的,应该了解它们的性能差异 1.最快的选择器:id选 ...
- jQuery的基本事件
1.用法 <!--jquery通过bind()这个方法来为元素绑定事件,可以传三个参数,type.data.fn--> <!--type表示一个或者多个事件的名称--> < ...
- jQuery代码优化:事件委托篇
推荐阅读原文:http://www.ituring.com.cn/article/467# 推荐11收藏 随着DOM结构的复杂化和Ajax等动态脚本技术的运用,事件委托自然浮出了水面.jQuery为绑 ...
- jquery的基本事件大全
].name); });jQuery.getScript( url, [callback] ) 使用GET请求javascript文件并执行. $.getScript(”test.js”, funct ...
- jQuery代码优化 事件委托篇
<转自 http://www.jb51.net/article/28770.htm> 参考文章: 解密jQuery事件核心 - 绑定设计(一) 参考文章: 解密jQuery事件核心 - ...
- ☀【jQuery 优化】jQuery基础教程(第3版)
jQuery代码优化:选择符篇 √ http://www.ituring.com.cn/article/377 jQuery代码优化:遍历篇 √ http://www.ituring.com.cn/a ...
- 编写高质量js代码
原文链接:http://code.tutsplus.com/tutorials/24-javascript-best-practices-for-beginners--net-5399 jquery代 ...
- js实例分析JavaScript中的事件委托和事件绑定
我们在学习JavaScript中,难免都会去网上查一些资料.也许偶尔就会遇到“事件委托”(也有的称我“事件代理”,这里不评论谁是谁非.以下全部称为“事件委托”),尤其是在查JavaScript的事件处 ...
- js事件委托篇(附js一般写法和js、jq事件委托写法)
参考: jQuery代码优化:事件委托篇 使用该技术能让你避免对特定的每个节点添加事件监听器:相反,事件监听器被添加在他们的父元素上,事件监听器会分析从子元素上冒泡上来的事件,并找到是哪个子元素事件. ...
随机推荐
- Python安装Numpy,matplotlib库
<1> Numpy是一款基于python的功能强大的科学计算包.要安装numpy首先你得先安装python. python的安装非常简单,本人安装的是python2.7 具体安装步骤如下: ...
- tomcat配置服务
1.在server中右键添加tomcat 2.双击tomcat打开配置窗口添加jvm参数 -Doapath="C:\exeye-workspace\exEyeWeb\oadoc" ...
- OpenLayers 3 入门教程
OpenLayers 3 入门教程摘要OpenLayers 3对OpenLayers网络地图库进行了根本的重新设计.版本2虽然被广泛使用,但从JavaScript开发的早期发展阶段开始,已日益现实出它 ...
- Spring注解原理
一.注解的基本概念和原理及其简单实用 注解(Annotation)提供了一种安全的类似注释的机制,为我们在代码中添加信息提供了一种形式化得方法,使我们可以在稍后某个时刻方便的使用这些数据(通过解析注解 ...
- java多线程 - 学习笔记
------------------------------------------------------------- sleep()与wait() sleep是线程类(Thread)的方法,wa ...
- WPF 如何加载图片
Uri ri = new Uri(AppDomain.CurrentDomain.BaseDirectory + "Resources/exp.jpg"); ImageSource ...
- BZOJ2716:[Violet 3]天使玩偶——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2716 样例输入 2 31 12 32 1 21 3 32 4 2 样例输出 1 2 ———————— ...
- 【bzoj2500】幸福的道路
Portal -->bzoj2500 Description 给你一棵树,每条边有边权,有两个给给的人第\(i\)天会从编号为\(i\)的点出发走这个点的树上最长距离,现在要你求一个最长的 ...
- Codeforces Round #427 (Div. 2) D dp
D. Palindromic characteristics time limit per test 3 seconds memory limit per test 256 megabytes inp ...
- Codeforces 938.C Constructing Tests
C. Constructing Tests time limit per test 1 second memory limit per test 256 megabytes input standar ...