jquery和widget源码分析(一)

栏目:eas cloud知识作者:金蝶来源:金蝶云社区发布:2024-09-16浏览:1

jquery和widget源码分析(一)

Jquery框架结构如图:


所有通过$();返回的jquery对象都是jQuery.fn.init实例对象,而jQuery.fn.init.prototype被指定为jQuery.fn,这样所有挂在jQuery.fn上的方法都是jQuery实例方法。
jQuery.fn=jQuery.prototype;从而所有jQuery实例的原型对象==jQuery.prototype,所以所有$(xxx) instanceof jQuery结果是true
jQuery实例是什么?


比如最常用的$(“#myId”),返回的结果就是一个init实例,它就是一个js对象,这个对象缓存了idmyId的元素、document等。同时这个对象拥有jQuery.fn里面定义的所有方法。

jQuery最常用的方法之一:extendjQuery.extend = jQuery.fn.extend =function() {
varoptions, name, src, copy, copyIsArray, clone,
//第0个参数为目标扩展对象
target= arguments[0] || {},
i= 1,//第一个参数为起始待扩展对象
length= arguments.length,
deep= false;

//Handle a deep copy situation
//如果第0个参数是布尔类型,则把第一个参数作为目标扩展对象,起始待扩展对象向后推一位
if( typeof target === "boolean" ) {
deep= target;
target= arguments[1] || {};
//skip the boolean and the target
i= 2;
}

//Handle case when target is a string or something (possible in deep copy)
if( typeof target !== "object" && !jQuery.isFunction(target) ){
target= {};
}

//extend jQuery itself if only one argument is passed
//除是否深拷贝,只传了一个对象,则被扩展对象设置为this
if( length === i ) {
target= this;
--i;
}
//除被扩展对象外,把剩余的所有对象作为扩展对象,顺序扩展到目标对象中
for( ; i < length; i++ ) {
//Only deal with non-null/undefined values
if( (options = arguments[ i ]) != null ) {
//Extend the base object
for( name in options ) {
src= target[ name ];
copy= options[ name ];

//Prevent never-ending loop
if( target === copy ) {
continue;
}

//Recurse if we're merging plain objects or arrays
if( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray= jQuery.isArray(copy)) ) ) {
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 );

//Don't bring in undefined values
}else if ( copy !== undefined ) {
//非深拷贝直接引用
target[name ] = copy;
}
}
}
}

//Return the modified object
returntarget;
};
此方法参数格式jQuery.extend([deep],object1,[object2,……]);deep为布尔类型,可以不传,如果传true则后面的拷贝为深拷贝,否则直接引用,如果自由一个object,这this默认成为目标扩展对象并返回this,否则object1为目标扩展对象,并返回object1,后续object依次对object1扩展,相同对象的相同属性后面覆盖前面。
jQuery缓存


jQuery缓存存放在jQuery.cache中,uuid作为key值,由jQuery自增长。data,removeData方法作为对外部的插入和移除接口。
data(elem[, name[,data,pvt]]);
1.如果elemdom节点,
elem[jQuery.expando]=id= ++jQuery.uuid;
data保存在cache[id]中;
2.否则id = jQuery.expando;
data保存在elem[jQuery.expando]

jQuery插件widget
Widgetjquery上的一个插件,代码就两三百行。使用时分为定义阶段,初始化和使用阶段。
如何定义一个widget组件? 通过$.widget = function( name, base, prototype ) {}函数定义。定义的结果是将widget构造函数:

$[ namespace ][name ] = function( options, element ) {

//allow instantiation without initializing for simple inheritance
if( arguments.length ) {
this._createWidget(options, element );
}
};
通过bridge(name, object)方法关联到$.fn[ name ]中,结构如下图。从此,所有的jquery实例都拥有了名为name的方法。

widget组件初始化?Widget组件依托于jquery对象。调用jquery对象上名为name的方法$(xxx).name(options)。初始化是传入的options为配置对象,此时的执行逻辑如下
var instance = $.data( this, name );
if ( instance ) {
instance.option(options || {} )._init();
if(!!window.debug){
$.log.end(start,((instance.element.attr("id"))?instance.element.attr("id"):"")+"-"+name+"-"+"Option"+":");
}
} else {
$.data(this, name, new object( options, this ) );
if(!!window.debug){
$.log.end(start,((options&&options.id)?options.id:"")+"-"+name+"-"+"Init"+":");
}
}
1. 查询这个jquery代表的dom节点上缓存的名为name的对象,这个对象即为widget的实例对象。如果存在,将options里面的内容更新到instance对象的option中,并执行_init()方法。所以要支持运行时改变配置需要复写_init()方法。2. 如果不存在,说明widget对象还没有初始化过,通过构造函数new一个widget对象,并通过jquery对象所表示的元素缓存,最终widget实例保存在jquery.cache中。3. 构造函数方法执行如下:

$[ namespace ][name ] = function( options, element ) {

//allow instantiation without initializing for simple inheritance
if( arguments.length ) {
this._createWidget(options, element );
}
}
此时调用$.Widget.prototype 中的_createWidget(eas的架构中没有覆盖这个方法),该方法如下:

new构造函数之前做过一次缓存,但是这里又重新缓存了一次,这样使得在_create方法执行之前保证缓存里面是有值的。在eas中通常使用_create作为组件创建的接口。
Widget组件使用?使用和初始化使用同一个入口,当options传入的是字符串是代表方法调用,当字符串的第一个字母为”_”时,调用将被直接返回。所以定义时,可以将方法名的第一个字符定义为”_”表示私有方法。不过这样并不表示这个方法就不能访问,这样只是限制正常的widget方法调用。如果直接从缓存中取对象还是可以执行这个私有方法的。
一个例子F7 ...
jqGrid ...


{:2_35:}辉哥威武,辉哥牛逼!下一堂客什么时候开讲
:handshake

jquery和widget源码分析(一)

Jquery框架结构如图:所有通过$();返回的jquery对象都是jQuery.fn.init实例对象,而jQuery.fn.init.prototype被指定为jQuery.fn,这样所有...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息