Successfully reported this slideshow.
jQuery源码学习<br />qijun.weiqj<br />
大纲<br />jQuery无架构*<br />常用的静态方法<br />解密万能构造器*<br />理解jQuery对象*<br />深入事件处理*<br />
jQuery无架构<br />源码之前,了无秘密<br />
varjQuery = function(selector,  context)  {<br />};<br />jQuery.extend = function(target, source) {<br />	// 回忆FD.common.a...
接着我们就可以扩展静态方法:<br />$.extendIf = function(target, src) {<br />}<br />// 注:丹侠在fdev4中提供了此方法,以此眷顾我们的fdev3<br />当然也可以这样<br />$...
可以更专业:<br />$.extend({<br />extendIf: function()…<br />	add: function()…<br />})<br />因为可以省略第一个参数, 此时target就是this, 即jQuery...
摘录:<br />jQuery.extend({<br />noConflict: function(deep) {<br />isFunction: function( obj ) {<br />		return jQuery.type(ob...
在jQuery中,我们可以这样:<br />$(‘#div’).addClass(‘error’);<br />$(‘ul.tabs’, elm).eq(0).click();<br />从上面我们知道 jQuery是一个函数, 从这里我们知道...
varjQuery = function() {<br />	return new jQuery.fn.init(selector, context);<br />};<br />jQuery.fn = { };<br />jQuery.fn....
重构一下:<br />varjQuery = function() {<br />	return new jQuery.fn.init(selector, context);<br />}<br />jQuery.fn = {<br />	in...
现在我们就可以扩展jQuery实例方法了<br />$.fn.ajax = function(url, options) {<br />}<br />专业点:<br />$.extend($.fn, {<br />	get: function(...
关于链式调用<br />$.fn.extend({<br />addClass: function() {<br />		…<br />		return this;<br />	}<br />toogleClass: function() {<...
经验建议<br />为了增加可读性, 避免不同类型API之间的链试调用<br />var elm = $(‘#id’);   //为了增加可读性, 避免过多的$, 只在合适的地方使用$构造<br />elm.removeClass(‘error...
轻松一下:浏览一下常用静态方法<br />工具方法<br />$.noConflict  // 由fdev-v4 默认调用,以兼容fdev-v3  所以应用中使用jQuery应该在一个closure中<br />$.trim<br />$.ea...
数组操作和类型检测<br />$.inArray	// 可以使用Array.indexOf代替<br />$.makeArray	// 很有用, 把任何东西变成数组<br />$.merge 		// 可惜了这个方法<br />$.type		...
AJAX和参数<br />$.param<br />$.paramSpecial中文jsonp调用代替$.param<br />$.unparam<br />$.parseJSON<br />$.parseXML<br />$.globalEv...
特性检测/浏览器检测/函数包装<br />$.support<br />$.browser<br />关于浏览器检测,文档中有一句话很有价值:<br />We recommend against using this property; <br...
虽然在api文档中有,但不常用的方法,<br />一般应用于jQuery内部,被相应的实例方法调用<br />$.fx<br />$.data<br />$.hasData<br />$.removeData<br />$.contains  ...
fdev-v4提供的静态方法<br />$.add<br />$.use<br />$.namespace<br />$.extendIf<br />$.unparam<br />$.paramSpecial<br />$.util.cooki...
万能构造器<br />jQuery对象是如何构造的<br />jQuery对象是数组吗?<br />构造成本有多大<br />
回顾一下<br />varjQuery = function() {<br />	return new jQuery.fn.init(selector, context);<br />}<br />jQuery.fn = {<br />	ini...
1. $(null|false|…);<br />2. $(element);<br />3. $(‘body’)<br />init: function(selector, context) (<br />		// 1. 支持空selecto...
		// 3. 字符串 body<br />		if (selector === 'body') {<br />this.context = document;<br />			this[0] = document.body;<br />thi...
4. $(function() {<br />console.debug(‘domready’)<br />})<br />5. $(array|collection)<br />//------------------------------...
6. $('<div></div>')<br />7. $('<div>')<br />8. $('<div />')<br />selector = [ doc.createElement( ret[1] ) ];<br />9. $('<i...
10. html片段和id选择器<br />$(‘<a href=“#”>这个html很复杂</a>') <br />jQuery.buildFragment( [ match[1] ], [ doc ] );  <br />1.  如果片段小...
12. css3选择器<br />$('div.myclass', [context]) --->  $(context).find('div.myclass')   <br /> ----> $(context). pushStack(…  ...
jQuery对象属性内存结构<br />看以上结构知道,jQuery对象是简单的轻量级对象,构造成本很小,<br />并且GC对小对象的回收效率非常高,所以从这上面讲不用担心效率和内存问题。<br />我在自己机子上构造了10万个jQuery对...
深入jQuery事件模型<br />页面中有下面代码:<br /><a href="#" class="link-a">Click Me A</a><br /><a href="#" class="link-b">Click Me B</a><...
在firebug的脚本监控中输入jQuery.cache<br />再查看节点的DOM<br />
在源码中有这样一个字段:1328行<br />jQuery.extend({	<br />expando: "jQuery" +<br />		 ( jQuery.fn.jquery + Math.random() ).replace( /D/...
一个节点一个事件一个handler<br />2197行:<br />elemData.handle = eventHandle = function() {			<br />	return jQuery.event.handle.apply(...
将上图数据结构展开<br />有了上图基础,看jQuery事件代码就容易多了,jQuery的事件也就不再神秘<br />
事件冒泡 live & delegate<br />问题:<br />有何区别<br />如果实现<br />其实是一个问题: 事件最终挂接到哪里?<br />
还是源码<br />delegate:  function( selector,  types,  fn) {<br />	return this.live( types, fn, selector);  <----- 第三个参数jq内部使用<...
jQuery.fn.live = function(types, fn, selector) {<br />var context = selector ? this : $(this.context);<br />	…<br />for ( ...
谢谢<br />谁教我做PPT啊!<br />
Upcoming SlideShare
Loading in …5
×

jQuery源码学习

2,171 views

Published on

  • Be the first to comment

jQuery源码学习

  1. 1. jQuery源码学习<br />qijun.weiqj<br />
  2. 2. 大纲<br />jQuery无架构*<br />常用的静态方法<br />解密万能构造器*<br />理解jQuery对象*<br />深入事件处理*<br />
  3. 3. jQuery无架构<br />源码之前,了无秘密<br />
  4. 4. varjQuery = function(selector, context) {<br />};<br />jQuery.extend = function(target, source) {<br /> // 回忆FD.common.apply<br />};<br />于是我们有了静态方法 $.extend(… <br />因为函数也是对象<br />
  5. 5. 接着我们就可以扩展静态方法:<br />$.extendIf = function(target, src) {<br />}<br />// 注:丹侠在fdev4中提供了此方法,以此眷顾我们的fdev3<br />当然也可以这样<br />$.extend($, {<br />extendIf: function() {<br /> …<br /> }<br /> add: function() {<br /> …<br /> }<br />})<br />
  6. 6. 可以更专业:<br />$.extend({<br />extendIf: function()…<br /> add: function()…<br />})<br />因为可以省略第一个参数, 此时target就是this, 即jQuery<br />在这里我们初步感觉到jQueryAPI的特点:<br />精简、灵活、还很智能, jQuery的流行最大的原因就在于此<br />jQuery中所有静态方法就是这样扩展的<br />注:但是我们把扩展jQuery的大任交给fdev-4维护小组,以避免名字空间冲突。应用中一般情况下不允许扩展jQuery对象<br />
  7. 7. 摘录:<br />jQuery.extend({<br />noConflict: function(deep) {<br />isFunction: function( obj ) {<br /> return jQuery.type(obj) === "function";<br /> },<br />isArray: Array.isArray || function( obj ) {<br /> return jQuery.type(obj) === "array";<br /> },<br />isWindow: function( obj ) {<br /> return obj && typeofobj === "object" && "setInterval" in obj;<br /> },<br />isNaN: function( obj ) {<br /> return obj == null || !rdigit.test( obj ) || isNaN( obj );<br /> },<br />
  8. 8. 在jQuery中,我们可以这样:<br />$(‘#div’).addClass(‘error’);<br />$(‘ul.tabs’, elm).eq(0).click();<br />从上面我们知道 jQuery是一个函数, 从这里我们知道<br />函数返回值是一个对象,并且有很多的实例方法, 这些方法用来操作相关节点<br />
  9. 9. varjQuery = function() {<br /> return new jQuery.fn.init(selector, context);<br />};<br />jQuery.fn = { };<br />jQuery.fn.init = function() {<br />};<br />jQuery.fn.init.prototype {<br />addClass: function() {<br /> },<br />removeClass: function() {<br /> }<br />};<br />从现在开始,我们的jQuery对象也有了addClass和removeClass方法<br />
  10. 10. 重构一下:<br />varjQuery = function() {<br /> return new jQuery.fn.init(selector, context);<br />}<br />jQuery.fn = {<br /> init: function() {<br /> },<br />addClass: function() {},<br />removeClass: function() {}<br />}<br />jQuery.fn.init.prototype = jQuery.fn<br />
  11. 11. 现在我们就可以扩展jQuery实例方法了<br />$.fn.ajax = function(url, options) {<br />}<br />专业点:<br />$.extend($.fn, {<br /> get: function()…<br /> post: function()…<br />})<br />更专业<br />$.fn.extend({<br /> bind: function() {…}<br />})<br />因为:$.fn.extend = $.extend = function(…, <br />
  12. 12. 关于链式调用<br />$.fn.extend({<br />addClass: function() {<br /> …<br /> return this;<br /> }<br />toogleClass: function() {<br /> …<br /> return this;<br /> }<br />hasClass: function() {<br /> return true|false;<br /> }<br />
  13. 13. 经验建议<br />为了增加可读性, 避免不同类型API之间的链试调用<br />var elm = $(‘#id’); //为了增加可读性, 避免过多的$, 只在合适的地方使用$构造<br />elm.removeClass(‘error’).addClass(‘success’);<br />elm.click(function() {<br /> …<br />});<br />
  14. 14. 轻松一下:浏览一下常用静态方法<br />工具方法<br />$.noConflict // 由fdev-v4 默认调用,以兼容fdev-v3 所以应用中使用jQuery应该在一个closure中<br />$.trim<br />$.each —— 可以对对象和数组进行迭代<br />$.extend —— FD.common.apply / YAHOO.lang.augmentObject<br />$.extendIf<br />$.grep —— <br />$.map<br />$.now —— new Date().getTime(), 方便加时间戳<br />
  15. 15. 数组操作和类型检测<br />$.inArray // 可以使用Array.indexOf代替<br />$.makeArray // 很有用, 把任何东西变成数组<br />$.merge // 可惜了这个方法<br />$.type // 返回类型字符串<br />$.isArray<br />$.isEmptyObject<br />$.isFunction<br />$.isPlainObject<br />$.isWindow<br />$.isXMLDoc<br />
  16. 16. AJAX和参数<br />$.param<br />$.paramSpecial中文jsonp调用代替$.param<br />$.unparam<br />$.parseJSON<br />$.parseXML<br />$.globalEval<br />$.ajax<br />$.ajaxSetup<br />以下方法调用$.ajax<br />$.get<br />$.post<br />$.getJSON<br />$.getScript<br />
  17. 17. 特性检测/浏览器检测/函数包装<br />$.support<br />$.browser<br />关于浏览器检测,文档中有一句话很有价值:<br />We recommend against using this property; <br />please try to use feature detection instead<br />jQuery.browser may be moved to a plugin in a future release of jQuery.<br />$.error ——当作assert使用<br />$.noop —— 空方法<br />$.proxy ——包装一个函数,改变this作用域<br />$.when<br />$.sub<br />
  18. 18. 虽然在api文档中有,但不常用的方法,<br />一般应用于jQuery内部,被相应的实例方法调用<br />$.fx<br />$.data<br />$.hasData<br />$.removeData<br />$.contains <br />$.queue<br />$.dequeue<br />$.cssHooks<br />
  19. 19. fdev-v4提供的静态方法<br />$.add<br />$.use<br />$.namespace<br />$.extendIf<br />$.unparam<br />$.paramSpecial<br />$.util.cookie<br />$.util.subCookie<br />$.util.substitute<br />
  20. 20. 万能构造器<br />jQuery对象是如何构造的<br />jQuery对象是数组吗?<br />构造成本有多大<br />
  21. 21. 回顾一下<br />varjQuery = function() {<br /> return new jQuery.fn.init(selector, context);<br />}<br />jQuery.fn = {<br /> init: function(selector, context) {<br /> },<br />
  22. 22. 1. $(null|false|…);<br />2. $(element);<br />3. $(‘body’)<br />init: function(selector, context) (<br /> // 1. 支持空selector<br /> if (!selector) {<br /> return this;<br /> }<br /> // 2. 原生dom节点<br />if (selector.nodeType) {<br />this.context = this[0] = selector;<br />this.length = 1;<br /> return this;<br /> }<br />
  23. 23. // 3. 字符串 body<br /> if (selector === 'body') {<br />this.context = document;<br /> this[0] = document.body;<br />this.selector = 'body';<br />this.length = 1;<br /> return this;<br /> }<br />现在我们知道:<br />jQuery对象是普通的Object, 不是Array, 只是包含的property为数字,所以看起来像数组<br />
  24. 24. 4. $(function() {<br />console.debug(‘domready’)<br />})<br />5. $(array|collection)<br />//--------------------------------------------------------------------------------------<br /> // 4. function<br /> } else if (jQuery.isFunction(selector)) {<br /> return jQuery.ready(selector);<br /> // 等效于 $(document).ready(function()…<br /> }<br /> // 5. collection / array<br /> return jQuery.makeArray(selector, this);<br />
  25. 25. 6. $('<div></div>')<br />7. $('<div>')<br />8. $('<div />')<br />selector = [ doc.createElement( ret[1] ) ];<br />9. $('<img>', {<br /> width: '100',<br /> height: '200'<br />});<br />selector = [ doc.createElement( ret[1] ) ];<br />jQuery.fn.attr.call( selector, context, true );<br />所以上述相当于 $(‘<img>’).attr(…<br />
  26. 26. 10. html片段和id选择器<br />$(‘<a href=“#”>这个html很复杂</a>') <br />jQuery.buildFragment( [ match[1] ], [ doc ] ); <br />1. 如果片段小于0.5K, 可cache, 以加快创建速度<br />2. createDocumentFragment()创建节点<br />3. innerHTML或 createTextNode来创建内容<br />11. $(‘#id’) // 注意,这里需要#, 因为要使用CSS3选 择器<br />elem = document.getElementById( match[2] );<br />
  27. 27. 12. css3选择器<br />$('div.myclass', [context]) ---> $(context).find('div.myclass') <br /> ----> $(context). pushStack(… 这一步会构造一个新的jQuery对象<br /> -----> jQuery.find === Sizzle;<br />所以采用css 3选择器的时候, 实际上会生成两个jQuery对象<br />不过不用担心,jQuery对象很小, 下面看看它的成本。<br />
  28. 28. jQuery对象属性内存结构<br />看以上结构知道,jQuery对象是简单的轻量级对象,构造成本很小,<br />并且GC对小对象的回收效率非常高,所以从这上面讲不用担心效率和内存问题。<br />我在自己机子上构造了10万个jQuery对象,大概占用32M内存空间。<br />
  29. 29. 深入jQuery事件模型<br />页面中有下面代码:<br /><a href="#" class="link-a">Click Me A</a><br /><a href="#" class="link-b">Click Me B</a><br /><script><br />(function($) {<br />$('a.link-a').click(function() {<br />console.debug('click a');<br />});<br />$('a.link-a').click(function() {<br />console.debug('click a2');<br />});<br />$('a.link-a').dblclick(function() {<br />console.debug('dbclick');<br />});<br />$('a.link-b').click(function() {<br />console.debug('click other');<br />});<br />})(jQuery);<br /></script><br />
  30. 30. 在firebug的脚本监控中输入jQuery.cache<br />再查看节点的DOM<br />
  31. 31. 在源码中有这样一个字段:1328行<br />jQuery.extend({ <br />expando: "jQuery" +<br /> ( jQuery.fn.jquery + Math.random() ).replace( /D/g, "" ),<br />
  32. 32. 一个节点一个事件一个handler<br />2197行:<br />elemData.handle = eventHandle = function() { <br /> return jQuery.event.handle.apply( eventHandle.elem, arguments ) :<br />};<br />2250行<br />if ( elem.addEventListener ) {<br />elem.addEventListener( type, eventHandle, false ); <br />} else if ( elem.attachEvent ) {<br />elem.attachEvent( “on” + type, eventHandle );<br />}<br />那么jQuery.event.handle应该是真正调用用户操作的地方<br />
  33. 33. 将上图数据结构展开<br />有了上图基础,看jQuery事件代码就容易多了,jQuery的事件也就不再神秘<br />
  34. 34. 事件冒泡 live & delegate<br />问题:<br />有何区别<br />如果实现<br />其实是一个问题: 事件最终挂接到哪里?<br />
  35. 35. 还是源码<br />delegate: function( selector, types, fn) {<br /> return this.live( types, fn, selector); <----- 第三个参数jq内部使用<br />}<br />
  36. 36. jQuery.fn.live = function(types, fn, selector) {<br />var context = selector ? this : $(this.context);<br /> …<br />for ( var j = 0, l = context.length; j < l; j++ )<br />jQuery.event.add( context[j], "live." + liveConvert( type, <br />}<br />总结:<br />1. live 事件挂接在 jQuery对象的context上(这里的context不是jQuery的第二个参数)一般为document<br />2. delegate事件挂接在当前jQuery对象包含的节点上<br />简单地说:<br />live挂接在document上(适合不复杂的冒泡)<br />delegate挂接在指定节点上 (比较精细)<br />
  37. 37. 谢谢<br />谁教我做PPT啊!<br />

×