ホームページ  >  記事  >  ウェブフロントエンド  >  jquery全体のアーキテクチャ分析と使い方を詳しく解説

jquery全体のアーキテクチャ分析と使い方を詳しく解説

php中世界最好的语言
php中世界最好的语言オリジナル
2018-04-23 11:22:191663ブラウズ

今回は、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

この匿名関数は、2 つのパラメータ (1 つは window、もう 1 つは未定義) を渡します。 js の変数にはスコープ チェーンがあることがわかっています。渡された 2 つの変数は匿名関数のローカル変数になり、より高速にアクセスされます。 windowオブジェクトを渡すことで、関数のパラメータもローカル変数として使用できるようになり、jqueryでwindowオブジェクトにアクセスする際にスコープを返す必要がなくなりました。スコープを最上位にチェーンすることで、ウィンドウ オブジェクトにより速くアクセスできるようになります。

パラメータ未定義

js が変数を検索するとき、js エンジンはまず関数自体のスコープ内で変数を検索します。変数が存在しない場合は、上向きに検索を続けます。変数が見つからない場合は、未定義の変数を返します。 unfineed は window オブジェクトのプロパティです。値を代入せずに unknown パラメータを渡すことにより、unknown を検索する際のスコープ チェーンを短くすることができます。自己呼び出し匿名関数のスコープ内では、未定義が本当に未定義であることを確認してください。未定義は上書きして新しい値を与えることができるためです。

jquery.fnとは何ですか?

 jQuery.fn = jQuery.prototype = {
              constructor: jQuery,
              init: function( selector, context, rootjQuery ) { ... },
                 // 一堆原型属性和方法
        };

上記のコードを分析すると、jQuery.fn が jQuery.prototype であることがわかりました。この方法で記述する利点は、コードが短いことです。その後、jquery は簡略化するために jquery の代わりに $ 記号を使用していることがわかりました。そのため、jquery フレームワークを使用するときは、$()、

constructorjQuery()

画像の説明

を使用することがよくあります。 jQuery オブジェクトは、新しい jQuery を通じてではなく、新しい 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 プロトタイプ メソッドであり、コンストラクタ。パラメーター セレクターとコンテキストのタイプを解析し、対応する検索を実行します。

パラメータコンテキスト: jQuery オブジェクト、DOM 要素、または通常の js オブジェクトのいずれかを渡すことができます。
パラメータ rootjQuery: document.getElementById() 検索失敗などの状況で使用される、ドキュメント オブジェクトを含む jQuery オブジェクト。

jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype
jQuery(selector [,context])

デフォルトでは、一致する要素の検索はルート要素のドキュメント オブジェクトから開始されます。つまり、検索範囲はドキュメント ツリー全体ですが、2 番目のパラメーターのコンテキストを渡して検索範囲を制限することもできます。例:

$('p.foo').click(function () {
            $('span',this).addClass('bar');//限定查找范围,即上面的context
   });
jQuery.extend()和jQuery.fn.extend()

メソッド jQuery.extend(object) および jQuery.fn.extend(object) は、2 つ以上のオブジェクトを最初のオブジェクトにマージするために使用されます。関連するソースコードは次のとおりです (部分):

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 の「静的メソッド」を追加します。次に、jQuery が導入されているこのメソッドを使用できます。次のように、公式 Web サイトでコードのデモを確認してください:

$.add(3,4); //return 7 
jQuery.fn.extend(object)

CSS 選択セレクター エンジン

jQuery が DOM を操作するために生まれたと言えます。jQuery が非常に強力である理由は、CSS セレクター エンジン Sizzle によるものです。 解析ルールはインターネットからの例を引用しています:

selector: " p > p + p.aaron input[type="checkbox"]"

解析規則:

1 右から左に最後のトークンを取り出します

2 例: [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()用于出栈

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

jQuery判断上传图片类型与大小方法详解

jQuery雪花飘落实现步骤(附代码)

以上がjquery全体のアーキテクチャ分析と使い方を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。