3分で遊ぶnoConflict()

9335 ワード

jQueryは現在最も広く使用されているフロントエンドフレームワークの一つであり、多くのサードパーティ製ライブラリとプラグインが開発されています.全体的なネーミング空間の汚染を避けるために、jQueryはjQueryを提供した.noConflict()メソッドは変数の競合を解決します.この方法は、間違いなく、非常に有効です.残念なことに、jQueryの公式ドキュメントはこの方法の説明がはっきりしていないので、多くの開発者はjQueryを呼び出すと分からない.noConflict()では、何が起こったのか、使用中に多くの問題が発生します.それでもjQuery.noConflict()の背後にある実現原理は依然としてWeb開発者が学ぶ価値があり,グローバルネーミング空間汚染問題のような解決の利器となっている.

jQuery.noConflict()の役割は?


  jQuery.noConflict()の存在は、同じページに複数のjQueryインスタンス、特に異なるバージョンのjQueryをロードできるようにする目的だけです.なぜ1つのページで複数の異なるバージョンのjQueryオブジェクトをロード/使用するのか不思議に思うかもしれません.一般的には、2つの状況があります.1つ目は、あなたのビジネスコードが最新版のjQueryライブラリを採用しているのに対し、あなたが選択したサードパーティプラグインが依存しているより古いバージョンのjQueryライブラリです.2つ目は、既存のビジネスコードが様々な理由で古いバージョンのjQueryライブラリを参照しているシステムを維持しています.あなたが新しく開発したモジュールは、他のバージョンのjQueryライブラリを採用しています.いずれの場合も、jQueryオブジェクト/メソッドの競合の問題に直面しなければなりません.幸いなことにjQuery.noConflict()はこの悩みを解決してくれました.

jQueryがロードされたときに何が起こりましたか?


 jQueryがページ参照/ロードされると、自己実行関数(匿名関数)にカプセル化され、提供されるすべての変数、関数、オブジェクトは匿名関数内部の実行可能環境内にあり、外部環境はグローバルネーミング空間の汚染を防ぐために呼び出すことができません.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

jQueryは匿名関数の内部で2つのグローバルオブジェクトを定義した:jQuery$、自分を外部環境に暴露した.開発者が慣用している様々な共通の方法は、jQuery.ajax()jQuery.css()などの2つのオブジェクトを介してアクセスされる.最初は、匿名関数の内部の同じオブジェクトjQuery(プライベート変数)を指し、匿名関数の内部のプライベート変数と関数にアクセスします.これにより、匿名関数は、実行後も内部のプライベート変数と関数がメモリに格納され、javascriptのゴミ回収メカニズムによって消去されません.
window.jQuery = window.$ = jQuery;

 jQueryがページにロードされると、現在のページにはjQuery$の2つのグローバル変数が存在する可能性があります(たとえば、他のサードパーティ製ライブラリがロードされ、その内部にも2つが定義されています).これにより、既存のオブジェクトが上書きされます(グローバルネーミング空間汚染).この問題を解決するために、jQueryは内部で既存のグローバル変数を先にキャッシュし、後続の呼び出しのためにプライベート変数_jQueryおよび_$に保存する.したがって、ページがjQueryライブラリをロードするときにjQueryおよび$のオブジェクトがまだ存在しない場合、_jQueryおよび_$はいずれもundefinedである.そうでなければ、既存のjQueryおよび$への参照が保存されます(以前に参照されたサードパーティ製ライブラリまたは異なるバージョンのjQueryライブラリからの可能性があります).その後、jQueryは上記のように、この2つのグローバル変数を上書きし、外部環境に露出します.これで、ページ上のグローバル変数jQueryおよび$は、導入されたばかりのjQueryライブラリを指している.
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,

// Map over the $ in case of overwrite
_$ = window.$,

// Otherwise expose jQuery to the global object as usual
window.jQuery = window.$ = jQuery;

jQuery.noConflict()の不思議な効果?


  メンテナンスしているシステムが1.7.0バージョンのjQueryライブラリを参照していると仮定し、新しく追加した機能で1.10.2バージョンのjQueryライブラリを参照しています.では、jQuery 1.7.0または2つのバージョンのjQueryライブラリを再利用する方法はありますか?答えは肯定的です.それはjQuery.noConflict()です.実際には、jQuery.noConflict()を使用すると、グローバル変数jQuery$を前に参照したオブジェクトにすぐに再指向することができます.不思議でしょ?これがjQueryが外部に露出する前に内部がキャッシュされた前に参照したオブジェクトである理由である. jQuery.noConflict()は、オプションのブール値パラメータを受け入れ、通常、デフォルト値はfalseです.このパラメータはどのような影響を及ぼしますか?実は、簡単です.jQuery.noConflict()またはjQuery.noConflict(false)が呼び出されると、グローバル変数$のみが以前の参照値にリセットされます.jQuery.noConflict()またはjQuery.noConflict(true)が呼び出されると、グローバル変数jQueryおよび$は、以前の参照値にリセットされて復元される.この点は非常に重要で、しっかり覚えておくことをお勧めします.jQuery.noConflict(false/true)を呼び出すと、現在のjQueryのインスタンスが返されます.このプロパティを使用して、jQueryの名前変更を実現できます.
// "Renaming" jQuery
var jayquery = jQuery.noConflict( true );
// Now we can call things like jayquery.ajax(), jayquery.css(), and so on

コードフラグメントを見て、不思議なnoConflict()を本当に理解しているかどうかをテストします.
<!-- jQuery and $ are undefined -->

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- jQuery and $ now point to jQuery 1.10.2 -->

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js">
<!-- jQuery and $ now point to jQuery 1.7.0 -->

<script>jQuery.noConflict();</script>
<!-- jQuery still points to jQuery 1.7.0; $ now points to jQuery 1.10.2 -->

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js">
<!-- jQuery and $ now point to jQuery 1.6.4 -->

<script>var jquery164 = jQuery.noConflict( true );</script>
<!-- jQuery now points to jQuery 1.7.0; $ now points to jQuery 1.10.2; jquery164 points to jQuery 1.6.4 -->

サードパーティ製ライブラリの競合を回避


以上のコードフラグメントは、マルチバージョンjQueryの競合をどのように解決するかを示しています.次に,jQueryライブラリとサードパーティライブラリの競合を解決しようと試みたが,以下に出現するコードフラグメントはjQueryの公式ドキュメントにあり,興味のあるプログラム猿は公式ドキュメントをよく読んでその違いを体得することができる.

No-Conflictモードを直接使用


  No-Conflictモードを使用すると、実はjQueryの名前を変更して呼び出します.
<!--   no-conflict  ,jquery.js prototype.js     . -->
<script src="prototype.js"></script>
<script src="jquery.js"></script>
<script>
 
var $j = jQuery.noConflict();
// $j    jQuery    .
 
$j(document).ready(function() {
    $j( "div" ).hide();
});
 
// $      prototype.js      
// document.getElementById(). mainDiv below is a DOM element, not a jQuery object.
window.onload = function() {
    var mainDiv = $( "main" );
}
 
</script>

自己実行関数パッケージの使用


この方法を使用すると、匿名関数の内部で標準の$オブジェクトを引き続き使用することができます.これも多くのjQueryプラグインが採用している方法です.なお、この方法では、関数内部でprototypeを使用することはできない.js定義の$オブジェクトです.
<!-- jquery.js prototype.js     . -->
<script src="prototype.js"></script>
<script src="jquery.js"></script>
<script>
 
jQuery.noConflict();
 
(function( $ ) {
    // Your jQuery code here, using the $
})( jQuery );
 
</script>

標準jQuery(document)を使用する.ready()関数


 jQueryライブラリが他のライブラリの前に導入された場合、jQuery内部で定義されたjQueryおよび$はサードパーティ製ライブラリで上書きされ、このときにnoConflict()を使用しても意味がありません.解決策は簡単で、jQueryの標準呼び出し方式を直接使用します.
<!-- jquery.js prototype.js     . -->
<script src="jquery.js"></script>
<script src="prototype.js"></script>
<script>
 
// Use full jQuery function name to reference jQuery.
jQuery( document ).ready(function() {
    jQuery( "div" ).hide();
});

//   
jQuery(function($){
    // Your jQuery code here, using the $
});
 
// Use the $ variable as defined in prototype.js
window.onload = function() {
    var mainDiv = $( "main" );
};

</script>