读jQuery之十四(触发事件核心方法)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
... 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
1
|
|
点击后,弹出1(事件handler),点确定跳转(默认行为)到了mail.sina.com.cn。因此,设计的触发事件的函数要考虑到这两种情况。
jQuery使用.trigger和.triggerHandler区分了这两种情况:
.trigger 执行事件hanlder/执行冒泡/执行默认行为
.triggerHandler 执行事件handler/不冒泡/不执行默认行为
.trigger/.triggerHandler的源码如下
1
2
3
4
5
6
7
8
9
10
11
|
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对象的第一个元素。如下
1
2
3
4
5
6
7
8
|
< 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的代码了
1
2
3
4
5
6
7
8
9
|
trigger: function ( event, data, elem, onlyHandlers ) {
// Event object or event type
var type = event.type || event,
namespaces = [],
exclusive;
......
} |
这就是jQuery.event.trigger的定义,省略了大部分。下面一一列举
1
2
3
4
5
|
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内使用。举个例子
1
2
3
4
5
6
7
8
9
|
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!') 触发非命名空间的点击事件
接着看
1
2
3
4
5
6
|
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"或对于已经触发过的事件直接返回。
往下
1
2
3
4
5
6
7
|
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"
续
1
2
3
4
|
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中可以用到(事件命名空间)。
往下是
1
2
3
4
5
|
// triggerHandler() and global events don't bubble or run the default action if ( onlyHandlers || !elem ) {
event.preventDefault();
event.stopPropagation();
} |
onlyHandlers 只在 .triggerHandler用到了,即不触发元素的默认行为,且停止冒泡。
下面是
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// 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里取。
接着是
1
2
3
4
|
// Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
return ;
} |
属性,文本节点直接返回。
下面是
1
2
3
|
// Clone any incoming data and prepend the event, creating the handler arg list data = data != null ? jQuery.makeArray( data ) : [];
data.unshift( event ); |
先将参数data放入数组,event对象放在数组的第一个位置。
接着是
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// 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对象。
接下是
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
|
// 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触发事件的通常写法,比如click事件的触发如下所示,感兴趣的朋友可以参考下
主要介绍了jQuery实现长按按钮触发事件的方法,可应用于手机端应用程序的开发中,非常具有实用价值,需要的朋友可以参考下
主要介绍了JQuery自动触发事件的方法,涉及trigger()方法完成模拟操作的相关技巧,需要的朋友可以参考下
主要介绍了不要使用jQuery触发原生事件的方法,需要的朋友可以参考下
在JQuery中,当给radio或checkbox添加一个change事件时,如果它的值发生变化就会触发change事件;本文将详细介绍如何利用JQuery触发Checkbox的change事件需要了解的朋友可以参考下
事件方法触发事件:jQuery中的事件方法在调用时如果传参数,表示绑定事件,如果不传参数,表示触发事件。;trigger()方法触发事件:使用trigger()方法可以触发指定事件。;triggerHandler()方法触发事件:...
jQuery触发式二级导航是一款基于jquery实现的二级导航菜单,支持回调函数下拉菜单导航条代码。
jquery点击复选框触发事件给input赋值-柯乐义</title><base target=”_blank” /> <style type=”text/css”> * { margin: 0; padding: 0; list-style-type: none; } a, img { border: 0; text-...
jquery 触发a链接点击事件 代码如下: ”btnSubmit”>确认</a></p> $(“.btnSubmit a”)[0].click(); ”tob”>这是文字</a></p>$(“#tob a”)[0].click(); 这里面很奇怪,有时候$(“.btnSubmit a”).click()可以,有...
本文实例讲述了基于jQuery的select下拉框选择触发事件实现方法。分享给大家供大家参考,具体如下: 我一直以来都认为,select 下拉框选择对选项 options 使用 onclick 注册事件即可,如下: <select> 选项一...
jQuery 事件以及处理方法 jQuery 事件 事件方法会触发匹配元素的事件,或将函数绑定到所有匹配元素的某个事件。 触发实例:$("button#demo").click() 上面的例子将触发 id="demo" 的 button 元素的 click 事件。 ...
安卓,ios,触发返回页面时的弹窗特效。此demo为mui所用时编写,你可以更改为jquery或者js原生的
本文实例讲述了jquery获取并修改触发事件的DOM元素。分享给大家供大家参考,具体如下: 需求 当点击关注后,改变按钮样式并显示取消关注,如图 实现 利用jQuery的 target获取到触发该事件的dom,然后修改它 ...
triggerTracker, 用于跟踪jQuery事件的jQuery调试工具 triggerTrackerTriggerTracker... 它是一个单独的JavaScript文件,当加载时,它向与jQuery事件触发和事件处理程序相关的浏览器的控制台提供输出。兼容性triggerTr
如何实现input输入框实时输入触发事件,下面有个不不错的示例使用jquery实现的,感兴趣的朋友可以参考下
jQuery对JavaScript操作DOM事件进行了封装,形成了更好的事件处理机制; 包括常用事件、事件绑定与解绑等。jQuery事件处理方法是jQuery的核心函数。 常用事件方法(教材P263表A-4): 分类 事件方法 描述 鼠标 click...