jQuery技术

jQuery event事件对象用法浅析(2)

字号+ 作者:H5之家 来源:H5之家 2016-01-14 14:17 我要评论( )

focusin/ focusout 可冒泡事件实现原理是,在事件捕获阶段监视特定元素的 focus/ blur 动作,捕获行为发生在 document 对象上,这样才能有效地实现所有元素都能可以冒泡的事件。 一旦程序监视到存在 focus/ blur 行

focusin/ focusout 可冒泡事件实现原理是,在事件捕获阶段监视特定元素的 focus/ blur 动作,捕获行为发生在 document 对象上,这样才能有效地实现所有元素都能可以冒泡的事件。 一旦程序监视到存在 focus/ blur 行为,就会触发绑定在 document 元素上的事件处理程序,该事件处理程序在内部调用 simulate 逻辑触发事件冒泡,以实现我们希望的可冒泡事件。源码如下:

 代码如下 复制代码


jQuery.each({focus: "focusin", blur: "focusout"}, function(orig, fix) {
        var attaches = 0,
            handler = function(event) {
                jQuery.event.simulate(fix, event.target, jQuery.event.fix(event), true);
            };
           
        jQuery.event.special[fix] = {
            setup: function() {
                if (attaches++ === 0) {
                    document.addEventListener(orig, handler, true);  
                    // 在 focus/blur 事件的捕获阶段添加事件监听,直接在 document 上监视,同时防止过多绑定
                }
            },
            teardown: function() {
                if (--attaches === 0) {
                    document.removeEventListener(orig, handler, true);
                }
            }
        };
    });

下面我们来分析我们应用 focusin 的过程,以便更清楚地理解其行为。

 代码如下 复制代码

$("p").focusin(function() {
    alert('yes!');
});

当我们第一次给 focusin 事件添加事件处理程序时,jQuery 会在 document 上会添加 handler 函数。之后每次用户触发 focus 事件时,浏览器都将捕获该事件并第一时间触发 handler 函数, handler 函数在其内部模拟了事件冒泡过程(trigger),由此实现可冒泡事件。

关于 focusin/focus 事件对 在 trigger 方法中的相关逻辑。源码如下:

 代码如下 复制代码


trigger: function(event, data, elem, onlyHandlers) {
        // ....
        // rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
        // 这里用于避免: 触发 elem.focus 默认行为时,二次触发 focusin 行为,因为已执行过。
     if (rfocusMorph.test(type + jQuery.event.triggered)) {
        return;
        }
        // ....
        // 特殊事件,主要是解决 focus 机制。如果 trigger 返回 false,则直接返回
        special = jQuery.event.special[type] || {};
        if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
            return;
        }
     if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {
            var bubbleType = special.delegateType || type;      
            if (!rfocusMorph.test(bubbleType + type)) {
         // type= focus/blur 这样可以在 elem 上同时触发 focus 和 focusin 事件
                cur = cur.parentNode;
            }
            // ...
        }
       // ....
    },

一: 避免二次触发 focusin 事件,当我们执行 elem.focus() 时,document 会再次捕获该事件并尝试再触发 focusin 事件。

 代码如下 复制代码

if (rfocusMorph.test(type + jQuery.event.triggered)) { return; }

二: 当 trigger('focus') 时,尽可能地应用原生事件,但不会冒泡。

 代码如下 复制代码

if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
     return;
}

三: 如果不满足应用原生事件的条件,则在当前元素上触发 focus 和 focusin 事件,并以 focusin 类型的事件向上冒泡。

 代码如下 复制代码

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • jQuery 动态添加与统计 实现代码

    jQuery 动态添加与统计 实现代码

    2015-11-04 14:05

  • jQuery css()选择器使用说明

    jQuery css()选择器使用说明

    2015-11-01 11:07

  • JQuery处理json与ajax返回JSON实例

    JQuery处理json与ajax返回JSON实例

    2015-10-22 12:28

网友点评
r