摘要:根据项目选型决定是否开启。为了压缩,可维护为了支持从而使用代替变量存储防冲突会用到,形如版本号声明最终调用的是这个原型实际上。功能检测统一兼容性问题。
概览
(function (){ (21 , 94) 定义了一些变量和函数 jQuery=function(); (96 , 293) 给jQuery对象添加一些方法和属性; (285 , 347) extend:jQuery扩展方法; (349 , 817) jQuery.extend : 扩展一些工具方法; (877 , 2856 ) Sizzle : 复杂选择器的实现; (2880, 3042 ) Callbacks : 回调对象:函数的统一管理 (3043, 3183 ) Deferred : 延迟对象:对异步的统一管理 (3184, 3295) support : 浏览器功能检测,确定浏览器对某些功能是否支持 (3380, 3652) data() : 数据缓存功能 (3653, 3797) queue()/dequeue() : 队列管理 (3803, 4299) attr() prop() val() addClass()等方法,对元素属性的操作 (4300, 5138) on() trigger()等方法,事件相关的方法,事件管理 (5140,6057) DOM操作:添加 删除 包装 获取 DOM筛选 (6058, 6620) css() : 样式操作 (6621, 7854) 提交的数据和Ajax()操作:ajax() load() getJson() (7855, 8584) animite() : 运动的方法 (8585, 8792) offset() :位置与尺寸的方法 (8804, 8821) JQuery对模块化的支持 (8826) window.jQuery = window.$ = jQuery;//对外提供的接口 })();匿名函数 :14
(function (window,undefined){ })(window)为什么传入window
对压缩和查找都有利
为什么传入undefined防止undefined在外部被修改
严格执行 :20"use strict"
低版本不支持,.net跟踪不支持。根据项目选型决定是否开启。
rootjQuery=jQuery(document);//:866
为了压缩,可维护
core_strundefined :30core_strundefined=typeof undefined
为了支持 IE9,从而使用type of xmlNode.method代替xmlNode.method !==undefined
变量存储 :33location = window.location //:33 document=window.document docElem=document.documenttElement core_concat = core_deletedIds.concat, //:52 core_push = core_deletedIds.push, core_slice = core_deletedIds.slice, core_indexOf = core_deletedIds.indexOf, core_toString = class2type.toString, core_hasOwn = class2type.hasOwnProperty, core_trim = core_version.trim,防冲突 :38
_jQuery=window.jQuery _$=window.$class2type={} :44
$.tpye() 会用到,clas2type形如 {"[objectt String]"}
core_version="2.0.3" :49版本号
jQuery声明最终$()调用的是这个
//:61 jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); },jQuery 原型
//:96 jQuery.fn = jQuery.prototype = { jquery: core_version, constructor: jQuery, init: function( selector, context, rootjQuery ) {...} } //:283 jQuery.fn.init.prototype = jQuery.fn;
实际上jQuery.prototype.init.prototype = jQuery.prototype。之后的的代码就可以写成颗粒化的调用操作,形如jQuery().css()。
通用正则 数字//:67 core_pnum = /[+-]?(?:d*.|)d+(?:[eE][+-]?d+|)/.source,非空字符,比如单词
core_rnotwhite = /S+/g,html标签
防止通过location.hash的XSS注入(#9521)
rquickExpr = /^(?:s*(<[wW]+>)[^>]*|#([w-]*))$/,独立空标签
比如
rsingleTag = /^<(w+)s*/?>(?:1>|)$/,IE驼峰转换
-ms-aaa-bbb转换成MsAaaBbb
rmsPrefix = /^-ms-/,普通驼峰转换
rdashAlpha = /-([da-z])/gi,jQuery.prototype :98 jquery:版本 :100
jquery: core_version,
constructor:修正指向问题constructor: jQuery,
不写容易被修改,例如
//Aaa Aaa.prototype.name="hello" Aaa.prototype.age=30 //Object AAA.prototype={ name:"hello", age:30 }init:初始化和参数管理 :101
对传入的参数分别处理
忽略的$(""), $(null), $(undefined), $(false)字符的
if 字符左侧是`<`且右侧是`>`且长度 大于3 //$("
return core_slice.call( this );
$("div"):{0:div,1:div,length:2} =>[div,div]
实际是调用slice
根据num返回全部或其中某个元素
get: function( num ) { return num == null ? this.toArray() : ( num < 0 ? this[ this.length + num ] : this[ num ] ); },pushStack():jQ对象入栈 :220
一个栈里放1个jQ对象,1个jQ对象包含1个或多个dom
each():遍历集合 :236工具方法jQuery.each
ready():DOM加载的接口 :240工具方法jQuery.reday.promise.done(fn)
slice():集合的截取 :247栈操作 this.pushStack( core_slice.apply( this, arguments ) );
first():集合的第一项this.eq( 0 )
last():集合的最后一项this.eq( -1 )
eq():集合的指定项 map():返回新集合return this.pushStack( jQuery.map(this, function( elem, i ) { return callback.call( elem, i, elem ); }));end():返回集合前一个状态
return this.prevObject || this.constructor(null);
push(): 内部使用core_push
sort(): 内部使用[].sort,
splice(): 内部使用splice: [].splice
jQuery.extend 拷贝方法 :285定义一些变量 if(){} 看是不是深拷贝情况 if(){} 看参数正确不 if(){} 看是不是插件情况 for(){ 可能有多个对象情况 if(){} 防止循环引用 if(){} 深拷贝 else if(){} 浅拷贝 }
防止循环引用
if ( target === copy ) { continue; }
深拷贝
if ( copyIsArray ) { copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy );
浅拷贝
target[ name ] = copy;工具方法
jQuery.extend({ expando:生成唯一jQ字符串(内部) noConflict():防止冲突 isReady: dom是否加载完(内部) readyWait:等待多少文件的计数器(内部) holdReady(): 推迟dom触发 ready():准备dom触发 isFunction():是否为函数 isArray():是否为数组 isWindow():是否为window isNumberic():是否为数字 type():判断数据类型 isPlainObjeect():是否为对象自变量 isEmptyObject():是否为空的对象 error():抛出异常 parseHTML():解析节点 parseJSON():解析JSON parseXML():解析XML noop():空函数 globalEval():全局解析js })expando 唯一映射 :351
生成唯一jQuery字符串,做映射关系用
expando: "jQuery" + ( core_version + Math.random() ).replace( /D/g, "" ),noConflict 防止冲突 :353
if ( window.$ === jQuery ) { window.$ = _$; } if ( deep && window.jQuery === jQuery ) { window.jQuery = _jQuery; } return jQuery;dom加载相关 jQuery.ready.promise
if ( document.readyState === "complete" ) { // 防止Ie的提前执行 setTimeout( jQuery.ready ); } else { // 若dom加载了则执行,否则监听完成后执行 document.addEventListener( "DOMContentLoaded", completed, false ); window.addEventListener( "load", completed, false ); }readyList holdReady(hold) :373
为true时执行ready,否则readyWait计数
if ( hold ) { jQuery.readyWait++; } else { jQuery.ready( true ); }ready(wait) :382
//如果有wait,或者ready,中止 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } jQuery.isReady = true; // 如果被触发,那么递减,如果需要则等待 if ( wait !== true && --jQuery.readyWait > 0 ) { return; } //如果有函数绑定,则执行。 readyList.resolveWith( document, [ jQuery ] ); // 触发任何绑定事件 if ( jQuery.fn.trigger ) { jQuery( document ).trigger("ready").off("ready"); }type(obj) :423
if ( obj == null ) { return String( obj ); } // 兼容: Safari <= 5.1 return typeof obj === "object" || typeof obj === "function" ? class2type[ core_toString.call(obj) ] || "object" : typeof obj;isWindow(obj) :415
不为空且window属性相同(undefined 没有属性)
return obj != null && obj === obj.window;isNumeric(obj) :417
typeof NaN 或 finite ==="number"
return !isNaN( parseFloat(obj) ) && isFinite( obj );parseHTML(data, context, keepScripts) :475
//校验输入 parsed=正则匹配data //单标签 return context.createElement( parsed[1] ) //多标签 //判断是否保留script parsed = jQuery.buildFragment( [ data ], context, scripts ) return jQuery.merge( [], parsed.childNodes );globalEval(code) :528
直接调用eval无法全局访问,必须先赋值
var indirect = eval; if "use strict" createElement document.head.appendChild( script ).parentNode.removeChild( script ) else indirect(code)camelCase :552
修正IE,驼峰转换
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase )nodeName( elem, name ) :556
全转小写判断是否相同
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();each( obj, callback, args ) :561
i=0 length=obj.length //若json则不存在 isArray=isArraylike(obj) if isArray for(;;) callback.call else for in callback.callmakeArray :615
类数组转数组
if isArraylike( Object(arr) jQuery.merge else core_pushinArray( elem, arr, i ) :632
indexOf
return arr == null ? -1 : core_indexOf.call( arr, elem, i );merge( first, second ) :636
获取2个变量的length
if 非json
for first[ i++ ] = second[ j ]
else
while first[ i++ ] = second[ j++ ]grep( elems, callback, inv ) :656
过滤新数组
for retVal = !!callback( elems[ i ], i ) if inv !== retVal ret.push( elems[ i ] )map( elems, callback, arg ) :676
//分别处理arr 和json for value = callback( elems[ i ], i, arg ); if ( value != null ) { ret[ ret.length ] = value; } return core_concat.apply( [], ret );proxy( fn, context ) :713
context 若是string content=fn(content) return function(){ return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ) } proxy.guid = fn.guid = fn.guid || jQuery.guid++access( elems, fn, key, value, chainable, emptyGet, raw ) :742
elems $("#div1")
fn 回调函数
key,value {background:"red"}
if type(key) ==="object" for access else if value !== undefined //空 //非函数 //函数swap( elem, options, callback, args ) :798
设置display可见
设置visibility:hidden
获取样式
属性再转回去
判断不是window
nodeType==1&&length #是节点 返回true return type === "array" ||type !== "function" &&( length === 0 ||typeof length === "number" && length > 0 && ( length - 1 ) in obj )createOptions(options)
将"once memory"=>{once:true,memory:true}
each
obj[flag]=truejQuery.Callbacks(options) :2880
once// fire for list
memory//add()时直接执行
unique//重复函数,add()时判断去重
stopOnFalse//fire for list
分别判断arg=aaa arg=aaa,bbb arg=[aaa,bbb] if menory==true fireremove(arg) :2965
分隔数组
has(fn) :2987jQuery.InArray
fireWith(context,args) :3018if list && ( !fired || stack ) if firing stack.push(args) else fire(args)Deferred(func) :3045
异步操作,延迟对象,基于$.Callbacks()
$.ajax(url).done(=>resolve).fail(=>reject)
成功
resolve=>fire
done=>add
失败
reject=>fire
fail=>add
notify=>fire
progress =>add
内部有个计数器,当$.when(a(),b(),c()) 中的arguments.length随着done()后减少到0,实际执行$.Deferred->resolve()
参数必须返回deferred延迟对象,不然则跳过该项。
统一兼容性问题。
checkOn复选框value值老版本chrome是‘’,新的是‘on’
optSelected下拉菜单子项第一项选中ie不会选中
noCloneChecked 克隆复选框的选中状态ie9,10没有选中
focusinBubbles 选中的冒泡机制 data 数据缓存 :3308key 自定义属性,set,get,access,remove,hasData,discard文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/52739.html
摘要:根据项目选型决定是否开启。为了压缩,可维护为了支持从而使用代替变量存储防冲突会用到,形如版本号声明最终调用的是这个原型实际上。功能检测统一兼容性问题。 概览 (function (){ (21 , 94) 定义了一些变量和函数 jQuery=function(); (96 , 293) 给jQuery对象添加一些方法和属性; (285 , 347) ...
摘要:异步实战状态管理与组件通信组件通信其他状态管理当需要改变应用的状态或有需要更新时,你需要触发一个把和载荷封装成一个。的行为是同步的。所有的状态变化必须通过通道。前端路由实现与源码分析设计思想应用是一个状态机,视图与状态是一一对应的。 React实战与原理笔记 概念与工具集 jsx语法糖;cli;state管理;jest单元测试; webpack-bundle-analyzer Sto...
摘要:本文分析的版本内部实现原理,版本已经去除了大量的对于旧版本浏览器的兼容性的处理,但是还是有部分源码是对不常见的或者老版本的浏览器进行处理,在看到这部分的时候如果感兴趣可以看一下,也可以直接跳过,个人一直认为学习旧版本浏览器的兼容是最没有收益 本文分析的JQuery2.0.3版本内部实现原理,2.0.3版本已经去除了大量的对于旧版本浏览器的兼容性的处理,但是还是有部分源码是对不常见的或者...
摘要:所有注册的处理方法并行执行,相互独立互不干扰。倘若某一个处理函数报错,则执行传入的,后续的处理函数将不被执行,否则最后一个处理函数调用。顺序由注册插件顺序决定,而不是由函数的执行时间。如果为此名称注册了插件,则返回。 Tapable https://github.com/webpack/ta...https://segmentfault.com/a/11... var Tapable ...
阅读 3800·2021-11-24 09:39
阅读 1809·2021-11-02 14:41
阅读 813·2019-08-30 15:53
阅读 3479·2019-08-29 12:43
阅读 1189·2019-08-29 12:31
阅读 3086·2019-08-26 13:50
阅读 795·2019-08-26 13:45
阅读 985·2019-08-26 10:56