學習作一個jq的插件,並用grunt構建打包。html
這個插件的功能很簡單,讓選擇器匹配元素運動到某個指定位置。有興趣學習作jq插件的同窗能夠看這個教程-》http://i5ting.github.io/How-to-write-jQuery-plugin/build/jquery.plugin.html,最好先研究過jq的源碼,這樣學起來比較容易,順便也能夠加深本身的jq源碼的理解。前端
如下是過程。node
肯定功能需求後,將還未封裝成插件的代碼寫出來(寫到這裏我發現我沒有留最開始那份代碼……因此略過)。在寫代碼的時候要留意什麼參數是必須由外部提供的,除此以外的代碼咱們應該所有封進插件,讓咱們的插件更獨立,耦合性更低,配置起來也比較簡單。對本文的插件來講,除了移動的元素要從外界傳進來,還須要傳入移動的終點和起點,其中起點其實能夠在插件內部設置。jquery
/** * init_moveTo_config: 初始參數配置 * param: * @obj: 移動的元素 * @opts: 用戶配置參數 */ function init_moveTo_config (obj,opts){ /* srcPosition 初始位置*/ var srcPosition = { left:$(obj).position().left, top:$(obj).position().top } /* 最終肯定的位置*/ opts = { left:opts.left?opts.left:srcPosition.left, top:opts.top?opts.top:srcPosition.top, speed:opts.speed } }
接着寫實現插件功能的業務邏輯。git
/** * init_moveTo_event: 插件業務邏輯 * param: * @obj: 移動的元素 * @opts: 用戶配置參數 */ function init_moveTo_event (obj,opts) { $(obj).animate( { left:opts.left+"px", top:opts.top+"px", opacity:'1' },opts.speed,"easeInOutBack",function() { }); }
由於這個插件的功能比較簡單,這樣把參數初始化和業務邏輯分離成單獨方法看起來有點小題大做,但我以爲這是一個良好的習慣,一是提升代碼可讀性,二也方便咱們之後對插件功能的擴展,易維護升級。github
接下來咱們套用jq插件的模板。這裏說一下 jQuery支持的2種插件方式,爲jQuery寫插件其實就是擴展jQuery的方法,擴展方式有兩種,一個是基於類擴展,一個是基於對象(原型)擴展。npm
基於類擴展json
基於類擴展能夠理解爲 爲jQuery類添加靜態方法,模板爲windows
$.myplugins={ plugin_a: function( args ) { //plugin_a代碼.. }, plugin_b: function( args ) { //plugin_b代碼.. } //...更多插件定義 };
基於類的擴展通常用於製做全局工具類,好比:性能優化
$.strTools = { trim:function( str ) { return str.replace( /\s+/g, "" ); } } $.strTools.trim(' hello world ');
ps: 將插件封裝在一個獨立的命名空間(如myPlugins)能夠避免命名空間內函數的衝突。
基於對象擴展
相對於基於類擴展,而基於對象擴展的插件有選擇器,且能夠傳入用戶配置參數,複用程度比較高,在實際中應用很是普遍。
基於對象擴展能夠理解爲 爲jQuery對象添加插件方法,模板爲:
;(function($) { /** * init_xxx_config: 初始參數配置 * param: * @obj: 命中元素(可選參數) * @opts: 用戶配置參數 */ function init_xxx_config (opts,[obj]){ //對初始參數的處理 } /** * init_xxx_event: 插件業務邏輯 * param: * @obj: 命中元素 * @opts: 用戶配置參數 */ function init_moveTo_event (opts,obj) { //編寫插件業務邏輯 } $.fn.xxx = function (options) { /* options:用戶的配置參數*/ var opts = $.extend({},$.fn.moveTo.defaults,options); return this.each(function() { var obj = $(this);//保存當前選擇器匹配對象指針 init_xxx_config (opts,[obj]);//調用初始化參數 init_xxx_event (opts,obj);//調用業務邏輯 }); }; /* defaults :插件默認的配置參數*/ $.fn.moveTo.defaults = { //... }; })(jQuery);
還有另外一個模板
(function($){ $.fn.extend({ pluginName:function(opt,callback){ } }) })(jQuery);
研究過jq源碼的同窗應該看過這段代碼jQuery.fn = jQuery.prototype ={...},也就是說jQuery.fn.extend(object); 是對jQuery.prototype擴展,就是爲jQuery類添加公共方法,jQuery類的實例均可以共享這個函數。
至此個人插件編碼就完成了。接下來學習使用grunt來構建打包。至於爲何要用grunt不用我來解釋了...
yahoo軍規講到前端性能優化的一點就是壓縮js代碼,雖然個人這份插件代碼很少(1.84 KB),壓縮以後變成700多字節,相差看起來不大,可是若是對其餘比較大的js文件,壓縮效果就很明顯了,就拿jq來講,jq未壓縮文件大概是268k,壓縮後(jquery.min.js)只有85k左右!我此次用grunt主要就是壓縮代碼。
順便說一下個人系統環境是windows。
確保npm跟node裝好後,安裝grunt-CLI: npm install -g grunt-cli ,安裝完畢後cmd敲grunt,結果以下:
進入項目文件夾,建立package.json和gruntFile.js文件。package.json管理項目信息(項目名稱,版本,做者,依賴列表),當你將項目發佈時,通常不會把node_modules裏的依賴包也放上去,若是那樣作可能你的項目就太大了,上傳和下載都不方便,那得到你項目的人要怎麼安裝項目須要的依賴包呢,很簡單,在項目文件夾敲npm install命令就能夠安裝全部package.json中聲明的依賴了,注意建立完package.json後要添加一些必要的信息,如devDependencies,否則使用npm install命令會沒法查找和更新依賴從而出錯。gruntFile.js則用來指導grunt作什麼,如今直接建立一個空的gruntFile.js文件就行了。
個人packege.json文件
{ "name": "moveToAnimate", "version": "1.0.0", "author": "jsal", "devDependencies": { } }
準備好package.json和gruntFile.js後(注意package.json內容的格式要正確),安裝grunt到該項目(不是全局安裝) npm install grunt --save-dev 。「—save-dev」的意思是,在當前目錄安裝grunt的同時,順便把grunt保存爲這個目錄的開發依賴項,也就是說會添加進packege.json的"devDependencies"的值裏面。
安裝完畢後輸入grunt,結果以下(請忽略個人文件路徑,那只是我我的的測試~)
表示咱們的grunt安裝好了,可是由於咱們沒有指定它要作什麼,因此纔是上面的結果。
接下來安裝grunt的官方插件,uglify插件,用來壓縮js代碼。
npm install grunt-contrib-uglify --save-dev
ps:帶有contrib的插件表示是grunt官方維護的插件。安裝完畢後package.json就會又多一個依賴信息:"grunt-contrib-uglify": " 安裝的版本號 "。
接下來配置gruntFIle.js,讓grunt使用uglify爲咱們壓縮代碼 。
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), //grunt參考的package.json配置文件的路徑 uglify: { //uglify插件的配置參數 options: { stripBanners: true, banner: '/*!<%= pkg.name %>-<%= pkg.version %>.js <%= grunt.template.today("yyyy-mm-dd") %>*/\n' },//設置了banner後banner的內容會出如今壓縮代碼的最開始的地方 //<%= pkg.name %> 得到了package.json中配置的name參數 build: { src: 'src/moveTo.js', //要壓縮的源文件 dest: 'build/<%= pkg.name %>-<%= pkg.version %>.js.min.js' //設置壓縮後的目標路徑及文件名 } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); //加載grunt-contrib-uglify模塊 grunt.registerTask('default',[ 'uglify']); //執行uglify }
配置無誤後再次輸入grunt就能執行壓縮動做啦,壓縮完的文件放在配置的build文件夾裏。
(完)