jQ的DOM事件机制: 结尾篇
发布在# 菜鸟解读 jQuery #2014年10月28日view:4727
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

前言:
    最近很忙...后续还有..
正文:
本篇是jqDOM事件系列的最后一篇,对剩余的内容进行收尾:
事件模拟:jQuery.event.special.simulate(),
快捷方法:click(), mouseover(), change(), ...
组合事件: toggle(), hover()

先来看事件模拟, 在jQ的dom事件相关代码中,有些地方会使用到 jQuery.event.simulate这个api的调用:

jQuery.event = {
    //...
    //模拟事件: 借助原生事件或者jQ事件对象,来为不支持冒泡的事件模拟冒泡过程
    //事件类型, 元素, 原生事件或jQ事件对象, 是否手动触发事件并模拟冒泡(boolean)
    simulate: function( type, elem, event, bubble ) {
        //多方聚合组合后的事件对象
        var e = jQuery.extend(
                new jQuery.Event(),
                event,
                {   
                    type: type,
                    isSimulated: true,
                    originalEvent: {}
                }
            );
        //需要冒泡
        if ( bubble ) {
            jQuery.event.trigger( e, null, elem );
        //触发事件,这里意味着是自然触发事件而非模拟触发
        } else {
            jQuery.event.dispatch.call( elem, e );
        }
        //阻止默认行为
        if ( e.isDefaultPrevented() ) {
            event.preventDefault();
        }
    }
};

下面来看下快捷方法:

jQuery.each( 
    ("blur focus focusin focusout load resize scroll unload click dblclick " +
    "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
    "change select submit keydown keypress keyup error contextmenu").split(" "), 
    function( i, name ){
        //事件的快捷方法
        jQuery.fn[ name ] = function( data, fn ) {
            if ( fn == null ) {
                fn = data;
                data = null;
            }
            //这里的处理非常好,传递参数就绑定事件,否则就触发事件
            return arguments.length > 0 ?
                //绑定事件
                this.on( name, null, data, fn ) :
                //触发事件
                this.trigger( name );
        };
        if ( jQuery.attrFn ) {
            jQuery.attrFn[ name ] = true;
        }
        //设置各类型的使用的修正对象,
        //主要针对鼠标事件和键盘事件设置修正方法
        if ( rkeyEvent.test( name ) ) {
            jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
        }
        if ( rmouseEvent.test( name ) ) {
            jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
        }
    }
);

jQ中可以使用toggle设置很多可以顺序触发的函数

jQuery.fn.extend({
    //...
    //绑定点击时, 轮训执行的事件监听函数
    toggle: function( fn ) {
        // N多函数的数组
        var args = arguments,
            guid = fn.guid || jQuery.guid++,
            i = 0,
            //要绑定的函数
            toggler = function( event ) {
                // 获取 lastToggle+fnId 的值,比上队列长度,也就是求要执行的函数的位置
                // 这里的%设计的很是巧妙,这样可以把事件队列变得可无限循环调用
                var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
                //设置 lastToggle+fnId 的值, 为前者的序列+1;
                jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
                //阻止默认行为
                event.preventDefault();
                //执行队列里的函数
                //这里巧妙的运用了闭包来对参数队列进行中的函数进行调用
                return args[ lastToggle ].apply( this, arguments ) || false;
            };
        //设置函数的标示ID
        toggler.guid = guid;
        while ( i < args.length ) {
            //为每个函数都绑定同一标示ID
            args[ i++ ].guid = guid;
        }
        //绑定事件 toggler,
        return this.click( toggler );
    },
    //...
});


感谢您的阅读,欢迎留言:斧正,提问,交流。

评论
发表评论
暂无评论
WRITTEN BY
前端狮子
JS前端开发工程师 :喜欢研究js,nodejs,html5; 希望结交更多朋友~
TA的新浪微博
PUBLISHED IN
# 菜鸟解读 jQuery #

本栏解读的jQ为1.7.2版本。 本人也是刚开始读起源码,在这里分享下成长的心得。 本人能力有限,也是接触JS不久的初学者,定会有不少解析不全不够明朗【甚至BUG】的地方, 希望各位牛牛多多留言斧正 感谢阅读 ps:由于工作不定时繁忙,本人也无法定期更新,但是会尽量抽时间学习,分享给大家

我的收藏