jQuery中noConflict()機制的沖突解決方法


  許多的JS框架類庫都選擇使用$符號作為函數或變量名,而且在實際的項目開發中,使用模板語言的話有可能"$"符號即為該模板語言的關鍵字。例如Veclocity模板語言,$是關鍵字.與jQuery一起使用可能會存在沖突(頁面中直接寫jq代碼,引入的js文件不存在該問題)。

  

  jQuery是使用$符號作為函數或變量名最為典型的一個。在jQuery中,$符號只是window.jQuery對象的一個引用,因此即使$被刪除,jQuery依然能保證整個類庫的完整性。

  jQuery的設計充分考慮了多框架之間的引用沖突。我們可以使用jQuery.noConflict方法來輕松實現控制權的轉交。

  在論述如何解決jQuery沖突之前,我們有必要先對noConflict函數做一個了解,解決沖突的方法就藏在里面。

  jQuery.noConflict();

  1,在省缺參數的情況下,運行這個函數將變量$的控制權讓渡給第一個實現它的庫。在運行完這個函數之后,就只能使用jQuery變量訪問jQuery對象(函數不帶參數),例如jQuery("div p")。

  注意該函數的使用時機:

    在jQuery導入之后,在其他沖突庫使用之前。

   2,當參數為true時,執行noConflict則會將$和jQuery對象本省的控制權全部移交給第一個產生他們的庫。

  以下為jQuery2.1.4的部分源碼:

    var

    // Map over jQuery in case of overwrite
    _jQuery = window.jQuery,

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

   jQuery.noConflict = function( deep ) {
    if ( window.$ === jQuery ) {
      window.$ = _$;
    }

    if ( deep && window.jQuery === jQuery ) {
      window.jQuery = _jQuery;
    }

    return jQuery;
   };

  容易理解的是,jQuery 通過兩個私有變量映射了 window 環境下的 jQuery 和 $ 兩個對象,以防止變量被強行覆蓋。一旦 noConflict 方法被調用,則通過 _jQuery, _$, jQuery, $ 四者之間的差異,來決定控制權的移交方式。

  

  接下來看看參數設定問題,如果deep沒有設置,_$覆蓋了window.$,此時jQuery的別名$失效了,但是jQuery變量未失效,仍可使用。此時如果有其他庫或代碼重新定義了$變量的話,其控制權就轉交出去了。反之deep設置為true時,_jQuery進一步覆蓋window.jQuery,此時$和jQuery都將失效。

  這種操作的好處是,不管是框架混用還是jQuery多版本共存這種高度沖突的執行環境,由於noConflict的控制權移交機制,以及本身返回違背覆蓋的私有變量jQuery對象,完全能夠通過變量映射的方式解決沖突。

  例一

  將 $ 引用的對象映射回原始的對象:

    jQuery.noConflict();
    // 使用 jQuery
    jQuery( "div p" ).hide();
    // 使用其他庫的 $()
    $( "content" ).style.display = 'none' ;
   例二
   恢復使用別名$,然后創建並執行一個函數,在這個函數的作用域中仍然將$作為jQuery的別名來使用。在這個函數中,原來的$對象是無效的。這個函數對於大多數不依賴於其他庫的插件都十分有效。
    
    jQuery.noConflict();
    (function($) {
       $(function() {
         // 使用 $ 作為 jQuery 別名的代碼
      //......
       });
    })(jQuery);
    // 其他用 $ 作為別名的庫的代碼
    //......
   例三
  可以將 jQuery.noConflict() 與簡寫的 ready 結合,使代碼更緊湊:
    jQuery.noConflict()(function(){
        // 使用 jQuery 的代碼
    });

    ... // 其他庫使用 $ 做別名的代碼
  例四
  創建一個新的別名用來在接下來的庫中使用jQuery對象。
    
    var j = jQuery.noConflict();
    // 基於 jQuery 的代碼
    j( "div p" ).hide();
    // 基於其他庫的 $() 代碼
    $( "content" ).style.display = 'none' ;
   例五
  完全將jQuery移到一個新的命名空間。
  
  var dom = {};
  dom.query = jQuery.noConflict( true );
         結果:
  // 新 jQuery 的代碼
  dom.query( "div p" ).hide();
  // 另一個庫 $() 的代碼
  $( "content" ).style.display = 'none' ;
  // 另一個版本 jQuery 的代碼
  jQuery( "div > p" ).hide();
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM