`

jquery触发事件

 
阅读更多

Snandy

Stop, thinking is the essence of progress.

读jQuery之十四(触发事件核心方法)

触发事件,或称模拟用户动作。比如点击,我们可以用代码去模拟用户点击,达到的效果与真实的鼠标点击是一样的。在 事件模块的演变 我使用了dispatchEvent(标准) 和fireEvent(IE)来主动触发事件。如下
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
<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的源码如下

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
分享到:
评论

相关推荐

    JQuery触发事件例如click

    当我们谈论到JQuery触发事件,特别是click事件时,我们通常是在讨论如何利用JQuery提供的方法,使得元素上的事件能够被程序模拟触发,或者是在不直接操作DOM的情况下,引发事件处理器执行。 在JQuery中,有几种方式...

    jQuery 1.9.1源码分析系列(十)事件系统之主动触发事件和模拟冒泡处理

    `jQuery.event.trigger`是jQuery触发事件的底层API,它支持触发各种类型的事件,包括普通浏览器事件和自定义事件。触发事件的过程主要包括以下步骤: 1. **初始化事件**:如果传入的`event`是一个事件类型字符串,...

    jQuery实现长按按钮触发事件的方法

    jQuery实现长按按钮触发事件的方法是移动设备和网页应用开发中的一项常见技术,主要目的是为了增强用户交互体验,尤其是在触摸屏设备上。通过长按按钮触发特定事件,开发者可以为用户提供更丰富的交互方式,比如在...

    JQuery自动触发事件的方法

    在现代Web开发中,使用JQuery自动触发事件是一个非常有用的技巧,可以帮助开发者模拟用户的交互行为,而无需用户手动去触发相应的事件。JQuery作为一款强大的JavaScript库,提供了多种方法来帮助开发者轻松实现这一...

    不要使用jQuery触发原生事件的方法

    然而,使用jQuery触发原生事件时,存在一定的风险和问题,本篇内容将深入分析这些风险,并提供解决方案。 首先,触发原生事件可能会引起一些不希望的副作用。例如,原生的`click`事件如果被触发,可能会导致页面上...

    jquery鼠标事件的小例子

    在JavaScript的世界里,jQuery是一个非常流行的库,它极大地简化了DOM操作、事件处理以及动画效果。这个"jquery鼠标事件的小例子"旨在帮助初学者更好地理解如何在jQuery中使用鼠标事件,同时结合CSS来实现交互效果。...

    读jQuery之十四 (触发事件核心方法)

    ### jQuery的触发事件方法 在上述传统方法的基础上,jQuery封装了更为简便和兼容性更好的事件触发方法。在jQuery中,.trigger和.triggerHandler是主要用来触发事件的两个方法。 - .trigger方法会触发指定事件的...

    为jQuery添加自定义事件机制

    总结,为jQuery添加自定义事件机制是通过`$.fn.extend`扩展jQuery功能,使用`on`和`off`来绑定和解除事件,通过`trigger`来触发事件,并可以传递参数。这种机制极大地丰富了jQuery的事件处理能力,使得开发者能够...

    JQuery绑定事件

    而事件委托则是利用事件冒泡机制,将事件绑定到父元素上,然后通过检查触发事件的原始元素来执行相应的处理函数,这样可以减少事件监听器的数量,提高性能。 在实际开发中,我们还需要了解如何移除事件绑定。这可以...

    jQuery触发式二级导航.zip

    综上所述,“jQuery触发式二级导航”涉及到了jQuery的选择器、事件处理、DOM操作、样式控制、动画效果、回调函数、响应式设计、浏览器兼容性、性能优化以及代码组织等多个方面。理解并掌握这些知识点,能够帮助...

    JQuery触发radio或checkbox的change事件

    在JQuery中,当给radio或checkbox添加一个change事件时,如果它的值发生变化就会触发change事件;本文将详细介绍如何利用JQuery触发Checkbox的change事件需要了解的朋友可以参考下

    jQuery Mobile事件参考手册.zip_jQuery Mobile事件参考手册

    《jQuery Mobile事件参考手册》是针对使用jQuery Mobile框架进行移动应用开发的重要参考资料。jQuery Mobile是一个功能丰富的库,专为触摸设备设计,它简化了在HTML5网页上创建响应式、跨平台用户界面的过程。该手册...

    jquery鼠标滚轮事件

    在Web开发中,鼠标滚轮事件是当用户滚动鼠标滚轮时触发的事件。这些事件包括`wheel`,这是HTML5新增的标准事件,以及jQuery中广泛使用的`mousewheel`事件。在jQuery中,通常我们使用`.on()`方法来绑定这些事件。 ``...

    jquery实现input输入框实时输入触发事件代码

    在本例中,我们探讨的是如何使用 jQuery 来实现在输入框(input)中实时输入时触发特定事件的功能。这对于构建动态交互的用户界面,如搜索建议、实时验证或数据过滤等场景非常有用。 首先,让我们分析提供的代码: 1...

    jquery 触发a链接点击事件解决方案

    jquery 触发a链接点击事件 代码如下: ”btnSubmit”&gt;确认&lt;/a&gt;&lt;/p&gt; $(“.btnSubmit a”)[0].click(); ”tob”&gt;这是文字&lt;/a&gt;&lt;/p&gt;$(“#tob a”)[0].click(); 这里面很奇怪,有时候$(“.btnSubmit a”).click()可以,有...

    jquery常用事件

    《jQuery常用事件详解》 jQuery,作为一款强大的JavaScript库,极大地简化了JavaScript的DOM操作、事件处理、动画设计以及Ajax交互。在Web开发中,jQuery的事件处理是其核心功能之一,它使得开发者能够轻松响应用户...

    jquery中的ajax方面的方法所触发的完整事件流演示

    在`jQuery.ajax()`的事件流中,我们可以触发并处理一系列的事件,这些事件包括: 1. `beforeSend`: 在发送请求之前调用,允许我们对XMLHttpRequest对象进行最后的修改,如添加自定义头信息。 2. `success`: 请求...

    jquery监听鼠标滚轮事件+js监听滚轮事件

    在这个例子中,我们绑定了滚轮事件到`body`元素,当滚轮事件触发时,会打印出滚动的方向。`event.originalEvent.wheelDelta`用于IE和Chrome,正数表示向上滚动,负数表示向下滚动;`-event.originalEvent.detail`...

    基于jQuery的select下拉框选择触发事件实例分析

    本文实例讲述了基于jQuery的select下拉框选择触发事件实现方法。分享给大家供大家参考,具体如下: 我一直以来都认为,select 下拉框选择对选项 options 使用 onclick 注册事件即可,如下: &lt;select&gt; 选项一...

Global site tag (gtag.js) - Google Analytics