继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

jquery中on函数的源码分析

myjeajea
关注TA
已关注
手记 5
粉丝 5
获赞 30

先用一个dome来看看on函数的使用场景:
<div id="a" style="width:100px;height:100px;background:red">
<p id="b" style="width:50px;height:50px;background:green"><span>h</span></p>
</div>
<script>
var a = $("#a");
a.on("click","p",function(e){
alert("gudalun");});
</script>
在调用on函数的时候到底发生了什么?
查看on函数的源码可以发现,它内部调用了jquery.event.add函数,on函数做了什么,实际就是这个函数做了什么?
这个函数的源码如下:
function( elem, types, handler, data, selector ) {
//以demo为例的话,这里的elem实际上是ID为#a的dom元素,types为click,handle是传进来的回调函数。
var tmp, events, t, handleObjIn,
special, eventHandle, handleObj,
handlers, type, namespaces, origType,
elemData = jQuery._data( elem );//查找这个dom中有没有缓存数据,这个结果返回了一个空的缓存对象.
if ( !elemData ) {//虽然为空但不是没有数值。
return;
}
if ( handler.handler ) {//回调函数这个对象没有handle字段,不进入这段代码 handleObjIn = handler;
handler = handleObjIn.handler;
selector = handleObjIn.selector;
}
if ( !handler.guid ) {
handler.guid = jQuery.guid++;//给这个函数初始化一个属性
}
if ( !(events = elemData.events) ) {
events = elemData.events = {};//缓存对象下初始化一个events属性和eventHandle属性。分别赋值一个空对象,和函数。这个函数就是后面绑定在这个dom元素上click事件的监听函数。
}if ( !(eventHandle = elemData.handle) ) {
eventHandle = elemData.handle = function( e ) {
return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
undefined;
};

        eventHandle.elem = elem;
    }
    types = ( types || "" ).match( core_rnotwhite ) || [""];//给types字符匹配给定的正则,返回一个数组。这里types=[click]
    t = types.length;
    while ( t-- ) {
        tmp = rtypenamespace.exec( types[t] ) || [];
        type = origType = tmp[1];
        namespaces = ( tmp[2] || "" ).split( "." ).sort();
        if ( !type ) {
            continue;
        }
        special = jQuery.event.special[ type ] || {};
        type = ( selector ? special.delegateType : special.bindType ) || type;
        special = jQuery.event.special[ type ] || {};
        handleObj = jQuery.extend({
            type: type,
            origType: origType,
            data: data,
            handler: handler,
            guid: handler.guid,
            selector: selector,
            needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
            namespace: namespaces.join(".")
        }, handleObjIn );//这里定义一个记录这个有关这个事件绑定函数信息的对象。
        if ( !(handlers = events[ type ]) ) {
            handlers = events[ type ] = [];//events就是前面elem.events,它是一个对象,也就是说在这个对象下,加一个type属性,初始化成一个数组。这个数组最终是用来存放DOM元素关于click事件的相关信息。在本例中是click事件,也可以是mouseover等其他时事件。
            handlers.delegateCount = 0;这个数组里面有个数据delegateCount,初始化是0.
            if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
        if ( elem.addEventListener ) {
                    elem.addEventListener( type, eventHandle, false );//这里给a这个dom 添加了一个click事件,事件处理函数是上面被初始化的eventHhandle,也就是说这个a被触发了click事件后,会调用这个函数。那我们传进来的函数呢?什么时候会调用?未完待续。。。。。。
                } else if ( elem.attachEvent ) {
                    elem.attachEvent( "on" + type, eventHandle );
                }
            }
        }

        if ( special.add ) {
            special.add.call( elem, handleObj );

            if ( !handleObj.handler.guid ) {
                handleObj.handler.guid = handler.guid;
            }
        }

        // Add to the element's handler list, delegates in front
        if ( selector ) {
            handlers.splice( handlers.delegateCount++, 0, handleObj );//
        } else {
            handlers.push( handleObj );
        }

        // Keep track of which events have ever been used, for event optimization
        jQuery.event.global[ type ] = true;
    }

    // Nullify elem to prevent memory leaks in IE
    elem = null;
},
打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP