您好,欢迎访问一九零五行业门户网

jquery总体架构分析与使用详解

这次给大家带来jquery总体架构分析与使用详解,jquery总体架构分析与使用的注意事项有哪些,下面就是实战案例,一起来看一下。
jquery的总体架构
(function( window, undefined ) {          // 构造 jquery 对象      var jquery = (function() {         var jquery = function( selector, context ) {                 return new jquery.fn.init( selector, context, rootjquery );             },                  // 一堆局部变量声明          jquery.fn = jquery.prototype = {             constructor: jquery,              init: function( selector, context, rootjquery ) { ... },                  // 一堆原型 属性和方法          };          jquery.fn.init.prototype = jquery.fn;          jquery.extend = jquery.fn.extend = function() { ... };          jquery.extend({                  // 一堆静态属性和方法          });          return jquery;      })();      window.jquery = window.$ = jquery;  })( window );
分析一下以上代码,我们发现jquery采取了匿名函数自执行的写法,这样做的好处就是可以有效的防止命名空间与变量污染的问题。缩写一下以上代码就是:
(function(window, undefined) {     var jquery = function() {}     // ...     window.jquery = window.$ = jquery; })(window);
参数window
匿名函数传了两个参数进来,一个是window,一个是undefined。我们知道,在js中变量是有作用域链的,这两个变量的传入就会变成匿名函数的局部变量,访问起来的时候速度会更快。通过传入window对象可以使window对象作为局部变量使用,那么,函数的参数也都变成了局部变量,当在jquery中访问window对象时,就不需要将作用域链退回到顶层作用域,从而可以更快的访问window对象。
参数undefined
js在查找变量的时候,js引擎首先会在函数自身的作用域中查找这个变量,如果没有的话就继续往上找,找到了就返回该变量,找不到就返回undefined。undefined是window对象的一个属性,通过传入undefined参数,但又不进行赋值,可以缩短查找undefined时的作用域链。在 自调用匿名函数 的作用域内,确保undefined是真的未定义。因为undefined能够被重写,赋予新的值。
jquery.fn是啥?
jquery.fn = jquery.prototype = {               constructor: jquery,               init: function( selector, context, rootjquery ) { ... },                  // 一堆原型属性和方法         };
通过分析以上代码,我们发现jquery.fn即是jquery.prototype,这样写的好处就是更加简短吧。之后,我们又看到jquery为了简洁,干脆使用一个$符号来代替jquery使用,因此,在我们使用jquery框架的使用经常都会用到$(),
构造函数jquery()
图片描述
jquery的对象并不是通过 new jquery 创建的,而是通过 new jquery.fn.init 创建的:
var jquery = function( selector, context ) {        return new jquery.fn.init( selector, context, rootjquery ); }
这里定义了一个变量jquery,他的值是jquery构造函数,在955行(最上面的代码)返回并赋值给jquery变量
jquery.fn.init
jquery.fn (上面97行)是构造函数jquery()的原型对象,jquery.fn.init()是jquery原型方法,也可以称作构造函数。负责解析参数selector和context的类型并执行相应的查找。
参数context:可以不传入,或者传入jquery对象,dom元素,普通js对象之一
参数rootjquery:包含了document对象的jquery对象,用于document.getelementbyid()查找失败等情况。
jquery.fn.init.prototype = jquery.fn = jquery.prototype jquery(selector [,context])
默认情况下,对匹配元素的查找从根元素document 对象开始,即查找范围是整个文档树,不过也可以传入第二个参数context来限定它的查找范围。例如:
$('p.foo').click(function () {             $('span',this).addclass('bar');//限定查找范围,即上面的context    }); jquery.extend()和jquery.fn.extend()
方法jquery.extend(object)和jquery.fn.extend(object)用于合并两个或多个对象到第一个对象。相关源代码如下(部分):
jquery.extend = jquery.fn.extend = function() {     var options, name, src, copy, copyisarray, clone,//定义的一组局部变量         target = arguments[0] || {},         i = 1,         length = arguments.length,         deep = false;
jquery.extend(object); 为jquery类添加添加类方法,可以理解为添加静态方法。如:
$.extend({  add:function(a,b){returna+b;}  });
便为 jquery 添加一个为add 的 “静态方法”,之后便可以在引入 jquery 的地方,使用这个方法了,
$.add(3,4); //return 7  jquery.fn.extend(object)
,查看一段官网的代码演示如下:
<label><input type="checkbox" name="foo"> foo</label><label><input type="checkbox" name="bar"> bar</label> <script>     jquery.fn.extend({         check: function() {             return this.each(function() {                 this.checked = true;                             });                                     },       uncheck: function()        {            return this.each(function()        {                this.checked = false;            });               }    });    // use the newly created .check()  method    $( input[type='checkbox'] ).check();</script>
css选择器引擎 sizzle
可以说,jquery是为操作dom而诞生的,jquery之所以如此强大,得益于css选择器引擎 sizzle,解析规则引用网上的一段实例:
selector:p > p + p.aaron input[type=checkbox]
解析规则:
1 按照从右到左
2 取出最后一个token  比如[type=checkbox]
{                                 matches : array[3]                                 type    : attr                                 value   : [type=                                 checkbox ]                             }
3 过滤类型 如果type是 > + ~ 空 四种关系选择器中的一种,则跳过,在继续过滤
4 直到匹配到为 id,class,tag  中一种 , 因为这样才能通过浏览器的接口索取
5 此时seed种子合集中就有值了,这样把刷选的条件给缩的很小了
6 如果匹配的seed的合集有多个就需要进一步的过滤了,修正选择器 selector: p > p + p.aaron [type=checkbox]
7 ok,跳到一下阶段的编译函数
deferred对象
开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们都不是立即能得到结果的。
通常的做法是,为它们指定回调函数(callback)。即事先规定,一旦它们运行结束,应该调用哪些函数。
但是,在回调函数方面,jquery的功能非常弱。为了改变这一点,jquery开发团队就设计了deferred对象。
简单说,deferred对象就是jquery的回调函数解决方案。在英语中,defer的意思是延迟,所以deferred对象的含义就是延迟到未来某个点再执行。
回顾一下jquery的ajax操作的传统写法:
$.ajax({  url: test.html,  success: function(){  alert(哈哈,成功了!);  },  error:function(){  alert(出错啦!);  }  });
在上面的代码中,$.ajax()接受一个对象参数,这个对象包含两个方法:success方法指定操作成功后的回调函数,error方法指定操作失败后的回调函数。
$.ajax()操作完成后,如果使用的是低于1.5.0版本的jquery,返回的是xhr对象,你没法进行链式操作;如果高于1.5.0版本,返回的是deferred对象,可以进行链式操作。
现在,新的写法是这样的:
$.ajax(test.html) .done(function(){ alert(哈哈,成功了!); }) .fail(function(){ alert(出错啦!); });
为多个操作指定回调函数
deferred对象的另一大好处,就是它允许你为多个事件指定一个回调函数,这是传统写法做不到的。
请看下面的代码,它用到了一个新的方法$.when():
$.when($.ajax(test1.html), $.ajax(test2.html))  .done(function(){ alert(哈哈,成功了!); })  .fail(function(){ alert(出错啦!); });
这段代码的意思是,先执行两个操作$.ajax(test1.html)和$.ajax(test2.html),如果都成功了,就运行done()指定的回调函数;如果有一个失败或都失败了,就执行fail()指定的回调函数。
jquery.deferred( func ) 的实现原理
内部维护了三个回调函数列表:成功回调函数列表、失败回调函数列表、消息回调函数列表,其他方法则围绕这三个列表进行操作和检测。
jquery.deferred( func ) 的源码结构:
jquery.extend({     deferred: function( func ) {            // 成功回调函数列表        var donelist = jquery.callbacks( once memory ),            // 失败回调函数列表            faillist = jquery.callbacks( once memory ),            // 消息回调函数列表            progresslist = jquery.callbacks( memory ),            // 初始状态            state = pending,            // 异步队列的只读副本            promise = {                // done, fail, progress                // state, isresolved, isrejected                // then, always                // pipe                // promise                       },            // 异步队列            deferred = promise.promise({}),            key;        // 添加触发成功、失败、消息回调函列表的方法        for ( key in lists ) {            deferred[ key ] = lists[ key ].fire;            deferred[ key + with ] = lists[ key ].firewith;        }        // 添加设置状态的回调函数        deferred.done( function() {            state = resolved;        }, faillist.disable, progresslist.lock )        .fail( function() {            state = rejected;        }, donelist.disable, progresslist.lock );        // 如果传入函数参数 func,则执行。        if ( func ) {            func.call( deferred, deferred );        }         // 返回异步队列 deferred        return deferred;    },}
jquery.when( deferreds )
提供了基于一个或多个对象的状态来执行回调函数的功能,通常是基于具有异步事件的异步队列。
jquery.when( deferreds ) 的用法
如果传入多个异步队列对象,方法 jquery.when() 返回一个新的主异步队列对象的只读副本,只读副本将跟踪所传入的异步队列的最终状态。
一旦所有异步队列都变为成功状态,“主“异步队列的成功回调函数被调用;
/* 请求 '/when.do?method=when1' 返回 {when:1} 请求 '/when.do?method=when2' 返回 {when:2} 请求 '/when.do?method=when3' 返回 {when:3} */ var whendone = function(){ console.log( 'done', arguments ); },     whenfail = function(){ console.log( 'fail', arguments ); }; $.when(     $.ajax( '/when.do?method=when1', { datatype: json } ),     $.ajax( '/when.do?method=when2', { datatype: json } ),     $.ajax( '/when.do?method=when3', { datatype: json } ) ).done( whendone ).fail( whenfail );属性selector用于记录jquery查找和过滤dom元素时的选择器表达式。
属性.length表示当前jquery对象中元素的个数。
方法.size()返回当前jquery对象中元素的个数,功能上等同于属性length,但应该优先使用length,因为他没有函数调用开销。
.size()源码如下:
size():function(){     return this.length; }
方法.toarray()将当前jquery对象转换为真正的数组,转换后的数组包含了所有元素,其源码如下:
toarray: function() {         return slice.call( this );     },
方法.get(index)返回当前jquery对象中指定位置的元素,或包含了全部元素的数组。其源
码如下:
get: function( num ) {        return num == null ?             // return a 'clean' array            this.toarray() :             // return just the object            ( num < 0 ? this[ this.length + num ] : this[ num ] );    },
如果没有传入参数,则调用.toarray()返回了包含有锁元素的数组;如果指定了参数index,则返回一个单独的元素,index从0开始计数,并且支持负数。
首先会判断num是否小于0,如果小于0,则用length+num重新计算下标,然后使用数组访问操作符([])获取指定位置的元素,这是支持下标为负数的一个小技巧;如果大于等于0,直接返回指定位置的元素。
eg()和get()使用详解:jquery常用方法及使用示例汇总
方法.each()用于遍历当前jquery对象,并在每个元素上执行回调函数。方法.each()内部通过简单的调用静态方法jquery.each()实现:
each: function( callback, args ) {         return jquery.each( this, callback, args );     },
回调函数是在当前元素为上下文的语境中触发的,即关键字this总是指向当前元素,在回调函数中return false 可以终止遍历。
方法.map()遍历当前jquery对象,在每个元素上执行回调函数,并将回调函数的返回值放入一个新jquery对象中。该方法常用于获取或设置dom元素集合的值。
map: function( callback ) {         return this.pushstack( jquery.map(this, function( elem, i ) {             return callback.call( elem, i, elem );         }));     },
原型方法.pushstack()创建一个新的空jquery对象,然后把dom元素集合放入这个jquery对象中,并保留对当前jquery对象的引用。
原型方法.pushstack()是核心方法之一,它为以下方法提供支持:
jquery对象遍历:.eq()、.first()、.last()、.slice()、.map()。
dom查找、过滤:.find()、.not()、.filter()、.closest()、.add()、.andself()。
dom遍历:.parent()、.parents()、.parentsuntil()、.next()、.prev()、.nextall()、.prevall()、.nextunit()、.prevunit()、.siblings()、.children()、.contents()。
dom插入:jquery.before()、jquery.after()、jquery.replacewith()、.append()、.prepent()、.before()、.after()、.replacewith()。
定义方法.push( elems, name, selector ),它接受3个参数:
参数elems:将放入新jquery对象的元素数组(或类数组对象)。
参数name:产生元素数组elems的jquery方法名。
参数selector:传给jquery方法的参数,用于修正原型属性.selector。
方法.end()结束当前链条中最近的筛选操作,并将匹配元素还原为之前的状态
end: function() {         return this.prevobject || this.constructor(null);     },
返回前一个jquery对象,如果属性prevobect不存在,则构建一个空的jquery对象返回。方法.pushstack()用于入栈,方法.end()用于出栈
相信看了本文案例你已经掌握了方法,更多精彩请关注其它相关文章!
推荐阅读:
jquery判断上传图片类型与大小方法详解
jquery雪花飘落实现步骤(附代码)
以上就是jquery总体架构分析与使用详解的详细内容。
其它类似信息

推荐信息