jQuery的on方法
2016-04-22 19:41
441 查看
jQuery中on方法的使用:
上面的两种使用方式都是可以的:
第一种是直接给页面中class中含有target的元素绑定上click事件;
第二种是把事件绑定在document上,然后判断当前的目标元素是否是class中含有target的元素进而来执行相应的事件(这种方式绑定上的事件,对之后动态添加的元素也同样有效果,通过事件冒泡来实现该操作)。
jQuery如何实现on方法的呢?
jQuery源码是这样写的:
jQuery中的
// eg1 $('.target').on('click', function(){ console.log(this); }); // eg2 $(document).on('click', '.target', function(){ console.log(this); });
上面的两种使用方式都是可以的:
第一种是直接给页面中class中含有target的元素绑定上click事件;
第二种是把事件绑定在document上,然后判断当前的目标元素是否是class中含有target的元素进而来执行相应的事件(这种方式绑定上的事件,对之后动态添加的元素也同样有效果,通过事件冒泡来实现该操作)。
jQuery如何实现on方法的呢?
jQuery源码是这样写的:
// on on: function( types, selector, data, fn, /*INTERNAL*/ one ) { ...... //省略部分代码(前面的代码是对传入的参数做一些处理) ...... return this.each( function() { // 调用jQuery.event.add方法 jQuery.event.add( this, types, fn, data, selector ); }); } // 调用jQuery.event.add方法 add: function( elem, types, handler, data, selector ) { ...... if ( !eventHandle ) { // 设置事件句柄方法 elemData.handle = eventHandle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? // 事件句柄的回调函数 // eventHandle.elem 事件对象 // arguments 传递的参数 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : undefined; }; // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events eventHandle.elem = elem; } ...... // 绑定了一个或多个方法 for ( t = 0; t < types.length; t++ ) { tns = rtypenamespace.exec( types[t] ) || []; type = tns[1]; namespaces = ( tns[2] || "" ).split( "." ).sort(); // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; // If selector defined, determine special event api type, otherwise given type type = ( selector ? special.delegateType : special.bindType ) || type; // Update special based on newly reset type special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers // 将一些数据信息放到handleObj中 handleObj = jQuery.extend({ type: type, origType: tns[1], data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join(".") }, handleObjIn ); // Init the event handler queue if we're the first handlers = events[ type ]; if ( !handlers ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener/attachEvent if the special events handler returns false if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { // Bind the global event handler to the element // 绑定上事件 if ( elem.addEventListener ) { elem.addEventListener( type, eventHandle, false ); } 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 ); } // console.log(handlers); // Keep track of which events have ever been used, for event optimization jQuery.event.global[ type ] = true; } ...... } // 调用jQuery.event.dispatct方法 dispatch: function( event ) { ...... if ( delegateCount && !(event.button && event.type === "click") ) { // 遍历元素 for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) if ( cur.disabled !== true || event.type !== "click" ) { selMatch = {}; matches = []; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; sel = handleObj.selector; if ( selMatch[ sel ] === undefined ) { selMatch[ sel ] = handleObj.needsContext ? jQuery( sel, this ).index( cur ) >= 0 : jQuery.find( sel, this, null, [ cur ] ).length; } // 将符合的元素事件数据对象放进matches中 if ( selMatch[ sel ] ) { matches.push( handleObj ); } } // 将matches和当前对象放到handlerQueue中 if ( matches.length ) { handlerQueue.push({ elem: cur, matches: matches }); } } } } ...... // Run delegates first; they may want to stop propagation beneath us // 遍历handlerQueue,里面是符合条件的数据对象 for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { matched = handlerQueue[ i ]; event.currentTarget = matched.elem; for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { handleObj = matched.matches[ j ]; // Triggered event must either 1) be non-exclusive and have no namespace, or // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { event.data = handleObj.data; event.handleObj = handleObj; // 执行我们调用on方法时所写的回调函数。 ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) .apply( matched.elem, args ); // console.log(ret); if ( ret !== undefined ) { event.result = ret; if ( ret === false ) { event.preventDefault(); event.stopPropagation(); } } } } } }
jQuery中的
one,
bind,
live,
delegate都是基于
on方法来改造的。
// one one: function( types, selector, data, fn ) { return this.on( types, selector, data, fn, 1 ); }, // bind bind: function( types, data, fn ) { return this.on( types, null, data, fn ); }, // live live: function( types, data, fn ) { jQuery( this.context ).on( types, this.selector, data, fn ); return this; }, // delegate delegate: function( selector, types, data, fn ) { return this.on( types, selector, data, fn ); }
相关文章推荐
- jquery 获得星期几-根据当前日期判断是星期几
- jQuery上传文件
- jQuery triger与trigerHandler的区别
- Jquery自动生成当前年份日期筛选框
- jquery完成图片的隐藏和显示
- Jquery根据id获取属性的一个奇怪问题
- jQuery学习(五)
- jQuery学习(四)
- jQuery学习(三)
- 15个值得开发人员关注的jQuery开发技巧和心得
- JQuery前端操作JSON
- jQuery中通过animate做一个简单的上下滑动的动画案例
- JQuery小技巧
- 用JavaScript 获取鼠标移动时的坐标(兼容:IE8、谷歌、Firefox)和用jquery方法的简单分析
- 在同一个页面使用多个不同的jQuery版本,让它们并存而不冲突
- 使用jQuery制作基础的Web图片轮播效果
- jquery animate回调函数小计
- 最牛x的滚动插件 – jquery的iscroll插件(附上下拉刷新消息demo)
- jquery.post()
- jQuery内部原理和实现方式浅析