在angular中使用jquery以及其它依賴於jquery庫的第三方插件的一種方法

angular中使用了webpack作爲依賴管理器,相較於之前在html中使用<script type="text/javascript" src="xxxx"的方式,使用webpack能夠實現使在須要某些依賴的時候才進行加載。性能雖然好,但在使用一些歷史的依賴於jquery的依賴時每每會出現找不到jquery的問題。javascript

情景

假設當前項目須要iCheck插件,此插件依賴於jqueryhtml

引用jQuery

javascript中,能夠經過向window對象上添加屬性的方式來實現全局變量。好比:java

var a = 'hello';
window.test = a;
console.log(test);

image.png

jquery能夠經過npm來進行安裝,安裝完成後可使用import語句將其引入到當前的項目中。想到項目中隨處使用$jQuery的關鍵字,則須要將$jquery聲明爲全局變量。打開angular中啓動模塊app.moudle.ts並向其中加入如下代碼:jquery

import * as jq from 'jquery';  ➊
declare var window: any; ➋

window.jQuery = jq; ➌
window.$ = jq; ➍
  • ➊ 從jquery中引入jquery,並將值賦予jq
  • ➋ 聲明window的類型爲any,以防在其上添加全局變量時發生錯誤
  • ➌ 添加全局變量jQuery
  • ➍ 添加全局變量$



只因此這樣使用是因爲jquery最後的幾行代碼以下,有興趣的能夠繼續研究下
if ( !noGlobal ) { ➊
    window.jQuery = window.$ = jQuery; 
}

return jQuery; ➋
}));
  • ➊ 使用import引用時noGlobal的值爲true
  • ➋ 將jQuery作爲返回值返回


如此一來即可以在項目中使用$jQuery了。但因爲typeScript是強類型的,因此在其它使用到$的地方還須要聲明$的類型爲任意類型。webpack

declare var $: any;
console.log($);

引用iCheck

iCheck官方未給出使用npm安裝的方法。咱們下載js文件後放到項目的任意文件中。iCheck並未像jquery同樣進行相應的return,因此也就不能像使用引入jquery同樣來進行引用了。這種狀況則可使用require方法來解決。假設當前icheck文件的存儲地址爲:./../bower_components/iCheck/icheck,則能夠在成功引用jquery後使用如下代碼引用icheckweb

import * as $ from 'jquery';
declare var window: any;
declare var require: any; ➊

window.jQuery = $;
window.$ = $;

require('./../bower_components/iCheck/icheck'); ➋
  • ➊ 定義require變量類型爲any
  • ➋ 使用require引用特定位置的文件

引用其它依賴

有些依賴已經能夠經過npm進行安裝,則引用起來就很簡單了。只須要使用如下語句則能夠完成引用:npm

require('依賴名');

總結

在angular中使用jquery時,主要解決的是向window中添加全局變量的問題。當window中存在$全局變量後,即可以在其它須要jquery功能的地方使用$()方法。當window中存在jQuery全局變量後,其它依賴於該jQuery的第三方依賴即可以成功的執行。app

大多依賴於jquery的庫會有如下格式:函數

(function($★) {
   // 功能代碼
})(window.jQuery || window.Zepto);
  • ➊ 若是window.jQuery已定義,則將★的值設置爲window.jQuery並當即執行function($)。
  • ➋ 若是window.jQuery未這義、window.Zepto已定義,則將★的值設置爲window.Zepto並當即執行function($)。
  • ➌ 若是window.jQuery、window.Zepto均未定義,則將★的設置設置爲undefined並當即執行function($)。

image.png

這種寫法還有一個好處是:此時 $變量爲局部變量,不會對全局的 $形成影響

若是在執行到該代碼時未引入window.jQuery,則window.jQuery、window.Zepto的值均爲undefined,此時執行function($){ 依賴於$的功能代碼 }的功能代碼時便會發生在undefined上調用xxx的錯誤。解決該錯誤的方法是在執行這段代碼前將jQuery添加到window中。也就是本文的解決的方案。性能

require與import

那麼爲何引入jquery時使用的是import,而引用iCheck使用的是require呢。這是由jquery與iCheck的功能特色以及require及import的特色所決定的:

名稱 功能特色 示例代碼
jquery 定義對象,返回對象 return jQuery
iCheck 執行了匿名函數 (function(){ 這裏是功能代碼 })()
名稱 功能 必然執行 做用域 執行時機
require('icheck') 將icheck的代碼複製到當前位置 應用上下文 當即執行
import * as $ from 'jquery'; 聲明變量$的來源 jquery.js文件內部 使用$時執行

以示例代碼爲例:咱們須要jquery中的返回的jQuery對象,因此須要import來進行引入(import * as $ from 'jquery';)此時$的值爲jQuery。對於iCheck而言咱們須要執行該匿名函數,因此使用require('iCheck')

簡單來講:require等於複製一份相同的js代碼放在require代碼所在的位置上,因此js代碼的做用域爲上下文;import等於建立一個js文件的引用(快捷方式),只有使用該引用時纔會嘗試找js文件要內容,此時js文件執行的做用域爲此js文件內部。

相關文章
相關標籤/搜索