- 浏览: 1173384 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
zhizhen23:
LZ 提供的链接地址失效了
重写的isPlainObject方法 -
LovingBaby:
LovingBaby 写道function fun() {}f ...
读jq之二(两种扩展) -
LovingBaby:
说的很清楚!jQuery作者为了实现简洁调用的苦心!高超的编程 ...
读jq之一(jq对象的组成) -
hard_ly:
...
将伪数组转换成数组 -
zlxzlxzlxzlxzlx:
这不能算是任意进制之间的转换,例如二十六进制、十二进制又该如何 ...
用递归实现十进制数转换N进制
触发事件,或称模拟用户动作。比如点击,我们可以用代码去模拟用户点击,达到的效果与真实的鼠标点击是一样的。
在 事件模块的演变 我使用了dispatchEvent(标准) 和fireEvent(IE)来主动触发事件。
如下
... dispatch = w3c ? function(el, type){ try{ var evt = document.createEvent('Event'); evt.initEvent(type,true,true); el.dispatchEvent(evt); }catch(e){alert(e)}; } : function(el, type){ try{ el.fireEvent('on'+type); }catch(e){alert(e)} }; ...
jQuery则完全没有用到dispatchEvent/fireEvent方法。它采用的是另外一种机制。
jQuery触发事件的核心方法是jQuery.event.trigger。它提供给客户端程序员使用的触发事件方法有两个:.trigger/.triggerHandler
一个事件的发生在某些元素中可能会导致两种动作,一个是默认行为,一个是事件handler。如链接A
<a href="http://mail.sina.com.cn" onclick="alert(1);">新浪邮箱</a>
点击后,弹出1(事件handler),点确定跳转(默认行为)到了mail.sina.com.cn。因此,设计的触发事件的函数要考虑到这两种情况。
jQuery使用.trigger和.triggerHandler区分了这两种情况:
.trigger 执行事件hanlder/执行冒泡/执行默认行为
.triggerHandler 执行事件handler/不冒泡/不执行默认行为
.trigger/.triggerHandler的源码如下
trigger: function( type, data ) { return this.each(function() { jQuery.event.trigger( type, data, this ); }); }, triggerHandler: function( type, data ) { if ( this[0] ) { return jQuery.event.trigger( type, data, this[0], true ); } },
可以看出,两者都调用jQuery.event.trigger。调用时一个没有传true,一个传了。传了true的triggerHander就表示仅执行事件handler。
此外还需注意一点区别:.trigger是对jQuery对象集合的操作,而.triggerHandler仅操作jQuery对象的第一个元素。
如下
<p>p1</p> <p>p1</p> <p>p1</p> <script> $('p').click(function(){alert(1)}); $('p').trigger('click'); // 弹3次,即三个p的click都触发了 $('p').triggerHandler('click'); // 仅弹1次,即只触发第一个p的click </script>
好了,是时候贴出jQuery.event.trigger的代码了
trigger: function( event, data, elem, onlyHandlers ) { // Event object or event type var type = event.type || event, namespaces = [], exclusive; ...... }
就是jQuery.event.trigger的定义,省略了大部分。下面一一列举
if ( type.indexOf("!") >= 0 ) { // Exclusive events trigger only for the exact event (no namespaces) type = type.slice(0, -1); exclusive = true; }
这一段是为了处理.trigger('click!')的情形,即触发非命名空间的事件。变量exclusive挂在事件对象上后在jQuery.event.handle内使用。举个例子
function fn1() { console.log(1) } function fn2() { console.log(2) } $(document).bind('click.a', fn1); $(document).bind('click', fn2); $(document).trigger('click!'); // 2
为document添加了两个点击事件,一个是具有命名空间的"click.a",一个则没有"click"。使用trigger时参数click后加个叹号"!"。从输出结果为2可以看出不触发命名空间的事件。总结一下:
.trigger('click') 触发所有的点击事件
.trigger('click.a') 仅触发“click.a” 的点击事件
.trigger('click!') 触发非命名空间的点击事件
接着看
if ( type.indexOf(".") >= 0 ) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split("."); type = namespaces.shift(); namespaces.sort(); }
这段就很好理解了,就是对.trigger('click.a')的处理,即对具有命名空间事件的处理。
接着看
if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { // No jQuery handlers for this event type, and it can't have inline handlers return; }
对于一些特殊事件如"getData"或对于已经触发过的事件直接返回。
往下
event = typeof event === "object" ? // jQuery.Event object event[ jQuery.expando ] ? event : // Object literal new jQuery.Event( type, event ) : // Just the event type (string) new jQuery.Event( type );
有三种情况
1,event 本身就是jQuery.Event类的实例
2,event是个普通js对象(非jQuery.Event类的实例)
3,event是个字符串,如"click"
续
event.type = type; event.exclusive = exclusive; event.namespace = namespaces.join("."); event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
需要注意exclusive/namespace/namespace_re挂到了event上了,在jQuery.event.handle中可以用到(事件命名空间)。
往下是
// triggerHandler() and global events don't bubble or run the default action if ( onlyHandlers || !elem ) { event.preventDefault(); event.stopPropagation(); }
onlyHandlers 只在 .triggerHandler用到了,即不触发元素的默认行为,且停止冒泡。
下面是
// Handle a global trigger if ( !elem ) { // TODO: Stop taunting the data cache; remove global events and always attach to document jQuery.each( jQuery.cache, function() { // internalKey variable is just used to make it easier to find // and potentially change this stuff later; currently it just // points to jQuery.expando var internalKey = jQuery.expando, internalCache = this[ internalKey ]; if ( internalCache && internalCache.events && internalCache.events[ type ] ) { jQuery.event.trigger( event, data, internalCache.handle.elem ); } }); return; }
这里是个递归调用。如果没有传elem元素,那么从jQuery.cache里取。
接着是
// Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; }
属性,文本节点直接返回。
下面是
// Clone any incoming data and prepend the event, creating the handler arg list data = data != null ? jQuery.makeArray( data ) : []; data.unshift( event );
先将参数data放入数组,event对象放在数组的第一个位置。
接着是
// Fire event on the current element, then bubble up the DOM tree do { var handle = jQuery._data( cur, "handle" ); event.currentTarget = cur; if ( handle ) { handle.apply( cur, data ); } // Trigger an inline bound script if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) { event.result = false; event.preventDefault(); } // Bubble up to document, then to window cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window; } while ( cur && !event.isPropagationStopped() );
这段代码很重要,做了以下事情
1,取handle
2,执行
3,执行通过onXXX方式添加的事件(如onclick="fun()")
4,取父元素
while循环不断重复这四步以模拟事件冒泡。直到window对象。
接下是
// If nobody prevented the default action, do it now if ( !event.isDefaultPrevented() ) { var old, special = jQuery.event.special[ type ] || {}; if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) && !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { // Call a native DOM method on the target with the same name name as the event. // Can't use an .isFunction)() check here because IE6/7 fails that test. // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch. try { if ( ontype && elem[ type ] ) { // Don't re-trigger an onFOO event when we call its FOO() method old = elem[ ontype ]; if ( old ) { elem[ ontype ] = null; } jQuery.event.triggered = type; elem[ type ](); } } catch ( ieError ) {} if ( old ) { elem[ ontype ] = old; } jQuery.event.triggered = undefined; } }
这一段是对于浏览器默认行为的触发。如form.submit(),button.click()等。
注意,由于Firefox中链接的安全性限制 ,jQuery对链接的默认行为都统一设计为不能触发。即不能通过.trigger()使链接跳转。
发表评论
-
如何定制你自己的jQuery
2015-01-12 08:38 2892jQuery随着版本的不断升级代码量也随之增加,从1.0. ... -
读jQuery之二十一(队列queue)
2013-11-21 14:13 2484queue模块在jQuery中分在Effects中,搜索整个 ... -
读jQuery之二十(Deferred对象)
2013-09-24 07:23 1214Deferred对象是由$.Deferred构造的,$.D ... -
读jQuery之十九(多用途回调函数列表对象)
2013-08-08 07:39 3172$.Callbacks是在版本1.7中 ... -
jQuery1.8的几个小变化
2013-05-18 07:57 1263一,.width() 和 .height()方法 1 ... -
读jQuery之十七(attribute/property/class)
2012-04-23 07:44 1666jQuery的属性模块提供了如下方法 attr/rem ... -
读jQuery之十六(事件代理)
2012-04-21 11:45 1859事件代理的实现原理很简单:利用浏览器中事件的冒泡(eve ... -
读jQuery之十五
2012-04-21 08:27 1276在之前的event-jq-0.2.js基础上继续提取jQuer ... -
读jQuery之十四
2012-04-20 22:12 1328最近看完了添加事件和删除事件的核心方法,忍不住想把jQu ... -
读jQuery之十八(元素位置)
2012-04-24 07:09 1749本篇所读源码版本为1.7.2 jQuer ... -
读jQuery之十二(删除事件核心方法)
2012-04-19 13:57 1559使用jQuery删除事件(或称解除事件绑定)有三个函数:unb ... -
读jQuery之十一(添加事件核心方法)
2012-04-19 07:07 2068上一篇提到jQuery中添加 ... -
读jQuery之十(事件模块概述)
2012-04-18 14:39 1839jQuery的事件模块是较 ... -
读jQuery之九(一些瑕疵)
2012-04-18 14:34 1325jQuery1.6.1 发布有一段时间了,发现一些冗余代 ... -
读jQuery之十八(元素位置)
2012-04-18 14:27 20本篇所读源码版本为1.7.2 jQuery中提供 ... -
读jq之八(原生事件对象的修复及扩充)
2010-12-04 09:13 2424由于各个浏览器中原生事件对象的 差异性 ,多数 JS库/框 ... -
读jq之七(判断点击了鼠标哪个键)
2010-12-03 18:31 2494jQuery丢弃了标准的 button 属性采用which ... -
jq中html()方法使用不当带来的陷阱
2010-05-29 10:54 5306.html方法当不传参数时用来获取元素的html内容,查看源码 ... -
jQuery1.4.2的一些瑕疵
2010-05-05 09:31 2283jQuery1.4.2 发布有一段时间了,发现一些多余的代 ... -
读jq之六(数据暂存)
2010-03-19 16:52 2615jq的$.data,$.removeData方法设计的很巧妙, ...
相关推荐
文章接着介绍了jQuery内部实现的事件触发核心方法jQuery.event.trigger。该方法允许开发者触发一个指定类型的事件,并允许传递数据给事件处理函数。它还区分了是否执行默认行为和是否冒泡,这对于复杂的事件处理逻辑...
在探讨jQuery实现事件添加的核心方法时,我们首先要明确几个概念:elem、types、handler和data,这些是jQuery.event.add方法的主要参数。Elem指的是要添加事件监听的HTML元素,通常是HTMLElement类型。Types则是指定...
在jQuery的事件模块中,`jQuery.event.add`是添加事件的核心方法。所有的`bind`、`one`、`live`等方法实际上都依赖于`jQuery.event.add`来完成事件的添加工作。这意味着,虽然表层API众多,但其底层的实现是统一和...
本文将深入探讨jQuery中事件处理的核心概念、方法以及常见的应用场景。 首先,jQuery提供了一种更加优雅的方式来处理DOM加载完成的事件。在JavaScript中,我们通常使用`window.onload`来确保所有资源(包括图片)...
以上只是jQuery核心API的一部分,实际使用中还有更多的方法和功能,如AJAX的全局事件、插件机制等。通过熟练掌握这些基础API,开发者可以轻松实现网页的动态交互,提高开发效率。在实际项目中,配合详细的文档和示例...
3. **强大的事件处理**:jQuery封装了JavaScript的事件处理,允许开发者用`.on()`、`.click()`等方法绑定事件,使事件处理更加便捷。 4. **丰富的动画效果**:jQuery的`.animate()`方法可以创建自定义动画,而`....
此外,`.off()`可以用来移除已绑定的事件,`.trigger()`可以触发特定的事件。 动画效果是jQuery的一大亮点。`.fadeIn()`, `.slideUp()`, `.animate()`等方法使得创建平滑的过渡效果变得简单。例如,`$("#element")....
3. **事件处理**:jQuery简化了事件绑定和触发,如`$("button").click(function() { ... })`用于在按钮点击时执行指定的函数。 4. **动画效果**:内置的`.fadeIn()`, `.slideUp()`, `.animate()`等方法,让创建动态...
3. **事件处理**:jQuery简化了事件绑定和解绑的过程,如`click(fn)`用于添加点击事件,`bind(eventType,fn)`绑定多种事件,`off(eventType)`解除事件绑定,`trigger(eventType)`触发事件。 4. **动画效果**:...
3. **事件处理(Events)**:jQuery提供了一种统一的方式来绑定和触发事件。例如,`click()`、`mouseover()`、`mouseout()`等方法用于绑定事件,`$(document).ready()`确保在DOM加载完成后执行指定的代码。 4. **...
3. **封装**: jQuery将复杂的JavaScript代码封装成简洁的方法,使得代码更易读、易写。 **二、jQuery主要功能** 1. **DOM操作**: jQuery提供了丰富的API用于创建、查找、修改和删除DOM元素,如`append()`、`prepend...
本篇文章将详细探讨 jQuery 实现多选项下拉框的核心概念、实现方法以及相关技术。 一、jQuery 概述 jQuery 是一个广泛使用的 JavaScript 库,它简化了 JavaScript 的DOM操作、事件处理、动画设计和Ajax交互。通过...
jQuery的核心特性可以使得网页动态化和交互变得简单。本项目以"基于jquery+canvas实现的拖动插件"为主题,利用jQuery与HTML5的Canvas API,创建了一个允许用户点击并拖动图形的功能。 Canvas是HTML5引入的一个强大...
jQuery的核心功能包括选择器(用于选取HTML元素)、遍历(遍历DOM树)、事件处理(绑定和触发事件)以及动画(创建平滑的视觉效果)。 在这个插件中,"jquery-syntax-3.1.1" 可能包含了以下组件和功能: 1. **...
2. **链式操作**: jQuery对象可以连续调用多个方法,这使得代码更加紧凑和易读。例如,`$("#element").hide().slideUp();`会先隐藏元素,然后执行滑动隐藏动画。 3. **DOM操作**: jQuery提供了丰富的API来操作DOM,...
jQuery提供了一种简洁的方式来绑定和触发这些事件,使代码更易读和维护。 动画效果是jQuery的一大亮点,它提供了多种内置方法来创建平滑的过渡和效果,如fadeIn()、fadeOut()、slideToggle()等。这些方法可以用于...
它将按键事件转换为可读的字符串,然后与预先绑定的函数进行匹配,触发相应的处理函数。开发者只需要提供一个或多个键的组合,即可轻松实现键盘快捷键的绑定。 三、使用方法 1. 引入jQuery和jQuery.hotkeys插件:...