javascript
JavaScript学习笔记(四)——jQuery插件开发与发布
jQuery插件就是以jQuery庫為基礎(chǔ)衍生出來的庫,jQuery插件的好處是封裝功能,提高了代碼的復(fù)用性,加快了開發(fā)速度,現(xiàn)在網(wǎng)絡(luò)上開源的jQuery插件非常多,隨著版本的不停迭代越來越穩(wěn)定好用,在jQuery官網(wǎng)有許多插件:
一、插件開發(fā)基礎(chǔ)
1.1、$.extend
在jQuery根命名空間下直接調(diào)用的方法可以認為是jQuery的靜態(tài)方法或?qū)傩?#xff0c;常常使用$.方法名來調(diào)用,使用$.extend這個靜態(tài)方法可以完成兩個功能:
1.1.1、擴展屬性或方法給jQuery
比如我們想給jQuery擴展一個用于快速向控制臺寫入日志的工具方法log,而不需要使用console.log且在沒有console.log的瀏覽器中使用其它的方法替代:
<script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript">$.extend({log: function(message) {console.log(message);}});$.log("控制臺日志");</script>運行結(jié)果:
1.1.2、擴展對象
var x={a:1};var y={a:2,b:3};var z={b:4,c:5};//使用第2個及后的對象擴展前面的對象,如果有則覆蓋 $.extend(x,y,z);$.log(x.a+","+x.b+","+x.c);運行結(jié)果:?
除了可以擴展對象的屬性,方法也可以擴展。
1.2、$.fn.extend
$.fn就是jQuery的原型,$.fn等于jQuery.prototype,$是jQuery的別名。$.fn.extend方法的作用是用于擴展jQuery實例對象,也就是我們從頁面中獲得的jQuery對象。
<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>extend</title></head><body><button>按鈕1</button><button>按鈕2</button><input type="text" value="username"/><input type="text" value="password"/><script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript">$.fn.extend({show:function(){$(this).click(function(){alert($(this).val()||$(this).html());});},log:function(){console.log($(this).val()||$(this).html());}});$("button").show();$("input[type=text]").log();</script></body></html>運行結(jié)果:
1.3、$.fn
在上面的示例中我們通過$.fn擴展了jQuery的原型,讓所有的jQuery實例對象都得到的擴展的方法,其它也可以直接修改jQuery.prototype來實現(xiàn),$.fn是jQuery.prototype的簡寫,源代碼如下:
示例代碼:
<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>extend</title></head><body><button id="btn1">按鈕1</button><button>按鈕2</button><input type="text" value="username"/><input type="text" value="password"/><script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript">$.fn.bgColor=function(color){this.css("background",color);}jQuery.prototype.color=function(color){this.css("color",color);}$("button,input").bgColor("lightGreen");$("button,input").color("red");</script></body> </html>運行結(jié)果:
二、插件開發(fā)
2.1、jQuery插件開發(fā)基本模式
jQuery插件開發(fā)的基本模式需要有一個私有作用域,javascript中默認沒有塊級作用域,一般通過閉包+IIFE模擬達到類似效果,在1.3中的示例是存在問題,因他它直接暴露在根命名空間下,可以使用如下辦法解決:
;(function(method) {method(window, window.document, jQuery);}(function(win, doc, $) {console.log("這是一個私有作用域,IIFE");$.fn.yourPluginName = function(options) {}}));前置的分號是為了與插件使用前的代碼劃清界線;兩個IIFE表達式的作用是:一個為了立即執(zhí)行且形成一個私有的塊級作用域,另一個是為了將后置的參數(shù)前置,方便看到IIFE執(zhí)行時帶的參數(shù)。帶參數(shù)的目的是為了加快查找的速度,提升性能。
插件的命名:
當(dāng)然一個好的插件應(yīng)該有一個容易記住且規(guī)范的名稱,能見名知意且不與別的插件同名沖突,文件的基本命名規(guī)范如下:
jQuery.YourPluginName-1.5.js 源代碼
jQuery.YourPluginName-1.5.min.js 壓縮代碼
2.2、獲取上下文
插件方法執(zhí)行范圍內(nèi)可以直接通過this關(guān)鍵字得到上下文,這里的this就是一個jQuery對象,無需使用$(this)將DOM轉(zhuǎn)換成jQuery對象。
;(function(method) {method(window, window.document, jQuery);}(function(win, doc, $) {console.log("這是一個私有的塊級作用域,IIFE");$.fn.myPlugin = function(options) {this.css({ //this是一個jQuery對象"color": "blue"});}}));$("button").myPlugin();運行結(jié)果:
上面的示例中是講$.fn的形式擴展,如果使用$.fn.extend情況還是一樣嗎?
;(function(method) {method(window, window.document, jQuery);}(function(win, doc, $) {console.log("這是一個私有的塊級作用域,IIFE");$.fn.extend({myPlugin2: function(options) {this.css({ //this是一個jQuery對象"background": "lightgreen"});}});}));$("button").myPlugin2();運行結(jié)果:
可見$.fn與$.fn.extend兩種方法中的this都是指jQuery對象,這也符合this指向調(diào)用他的對象的原則。
2.3、第一個jQuery插件
這是一個Hello World示例,完成一個可以變長的元素插件,指定每次增加長度參數(shù),在指定的HTML元素后增加一個加號點擊加號可以將元素加寬指定長度。
jQuery.SuperPlus-1.0.js文件內(nèi)容如下:
; (function(method) {method(window, window.document, jQuery); }(function(win, doc, $) {$.fn.SuperPlus = function(length) {$.each(this, function(index, obj) {$("<span/>").html("+").css("cursor", "pointer").click(function() {$(obj).width($(obj).width() + length);}).insertAfter(obj);});} }));HTML頁面:
<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>jQuery插件</title></head><body><button>按鈕1</button><br /><button>按鈕2</button><br /><input type="text" value="username" /><br /><input type="text" value="password" /><script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script><script src="js/SuperPlus/jQuery.SuperPlus-1.0.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript">$("button").SuperPlus(10);$("input").SuperPlus(50);</script></body></html>運行結(jié)果:
插件中使用each的原因是jQuery選擇器選擇的內(nèi)容默認就是一個包裝集,中間有多個元素,包裝集中含有多個DOM元素,each中的元素就不再是jQuery對象而是一個DOM對象。
練習(xí):$("#div1,#div2").superDiv(50,50,3,"blue");在div1與div2中都添加3個長50,寬50的div,設(shè)置背景色為藍色,點擊時div消失,添加的div要求橫向排列,間隔為寬高的1/10。
$("#div1,#div2").superDiv({width:50,height:50,color:"red",before:function(){},after:function(){}});
2.4、鏈?zhǔn)骄幊?/h2>
幾乎在所有基于“類型”的語言中如果調(diào)用一個方法后將對象作為方法參數(shù)返回則就會形成鏈?zhǔn)骄幊?#xff0c;如:
return $.each(this, function(index, obj) {$("<span/>").html("+").css("cursor", "pointer").click(function() {$(obj).width($(obj).width() + length);}).insertAfter(obj);});上面的示例中當(dāng)$.each循環(huán)完成后返回this對象,返回的仍然是一個jQuery對象,所以可以繼續(xù)jQuery編程。
$("button").SuperPlus(10).height(26).width(100).css("color","blue");運行結(jié)果:
2.5、參數(shù)與默認值
參數(shù)是插件對外部提供的接口,靈活的參數(shù)會讓插件變得使用方便,這里主要從3個方面來講參數(shù):
2.5.1、默認值
最好為每個參數(shù)提供默認值,有缺省的默認值會減少錯誤,如:
$("input").SuperPlus();這樣沒有提供參數(shù),點擊時沒有任何效果,也沒有錯誤提示,應(yīng)該給參數(shù)增加一個默認值,如:
; (function(method) {method(window, window.document, jQuery); }(function(win, doc, $) {$.fn.SuperPlus = function(length) {length=length||3;return $.each(this, function(index, obj) {$("<span/>").html("+").css("cursor", "pointer").click(function() {$(obj).width($(obj).width() + length);}).insertAfter(obj);});} }));length=length||3意思是如果用戶沒有提供參數(shù)則length的值為3。
2.5.2、參數(shù)對象
上面的示例中只有一個參數(shù),直接作為方法的參數(shù)沒有任何問題,但如果參數(shù)非常多,且都要默認值,處理就很麻煩,最好的辦法是使用參數(shù)對象:
<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>jQuery插件</title></head><body><button>按鈕1</button><br /><button>按鈕2</button><br /><input type="text" value="username" /><br /><input type="text" value="password" /><script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script><script src="js/SuperPlus/jQuery.SuperPlus-1.0.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript">$("button").SuperPlus({length: 100});$("input").SuperPlus({color: "red"});</script></body> </html>插件:
; (function(method) {method(window, window.document, jQuery); }(function(win, doc, $) {$.fn.SuperPlus = function(options) {//默認參數(shù)var setting={length:3,color:"blue"};//使用用戶的參數(shù)覆蓋默認參數(shù) $.extend(setting,options);return $.each(this, function(index, obj) {$("<span/>").html("+").css("cursor", "pointer").css("color",setting.color).click(function() {$(obj).width($(obj).width() + setting.length);}).insertAfter(obj);});} }));運行結(jié)果:
2.5.2、參數(shù)類型
參數(shù)對象的類型可是屬性,方法,對象,數(shù)組等多種形式,也可以使用回調(diào)方法,比如這里我們要為插件增加一個執(zhí)行后的事件changeAfter,當(dāng)目標(biāo)元素被修改后觸發(fā)。
修改后的插件:
; (function(method) {method(window, window.document, jQuery); }(function(win, doc, $) {$.fn.SuperPlus = function(options) {//默認參數(shù)var setting={//每次增加的長度length:3,//加號的顏色color:"blue",//回調(diào)事件,點擊后執(zhí)行changeAfter:null };//使用用戶的參數(shù)覆蓋默認參數(shù) $.extend(setting,options);return $.each(this, function(index, obj) {$("<span/>").html("+").css("cursor", "pointer").css("color",setting.color).click(function() {$(obj).width($(obj).width() + setting.length);//如果用戶指定了回調(diào)事件if(setting.changeAfter){//執(zhí)行用戶帶入的方法將當(dāng)前對象作為參數(shù)帶出 setting.changeAfter($(obj));}}).insertAfter(obj);});} }));HTML頁面:
<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>jQuery插件</title></head><body><button>按鈕1</button><br /><button>按鈕2</button><br /><input type="text" value="username" /><br /><input type="text" value="password" /><script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script><script src="js/SuperPlus/jQuery.SuperPlus-1.0.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript">$("button").SuperPlus({length: 100,changeAfter:function(obj){//如果長度超過300則變成100if($(obj).width()>300){$(obj).width(100);}}});$("input").SuperPlus({color: "red"});</script></body> </html>運行結(jié)果:
2.6、命名空間與面向?qū)ο?/h2>
給插件正確的命名空間是非常重要要的,這樣可以避免和其它插件或代碼沖突,可以使用閉包,模塊等方法實現(xiàn)。按照jQuery的約定,只使用一個命名空間。
在插件中盡量只使用jQuery.fn下的一個名稱,名稱越多沖突的可能性就越大,成熟的插件會做沖突處理,就像多個jQuery庫共存的道理是一樣的。
另外對于復(fù)雜的插件盡量將代碼封裝,不要使用函數(shù)式的編程方式,可以通過構(gòu)造函數(shù),IIFE,原型繼承等方法達到目的。
2.7、插件與關(guān)聯(lián)的CSS
如果插件中會使用到大量的CSS樣式,則不推薦使用jQuery的方式去添加樣式,應(yīng)該做成一個插件單獨使用CSS文件,命名可以參考如下方式:
jQuery.YourPluginName-1.5.css 樣式
樣式一定要注意不要修改與插件無關(guān)的元素,甚至連CSSReset都不應(yīng)該有,推薦使用一個相對不易沖突的名稱所有的樣式都在該類樣式下,注意ID樣式是不允許重復(fù)的,因為要考慮一個頁面中同時使用多個插件實例的情況。
2.8、壓縮與混淆
壓縮為是了減小插件的體積。JavaScript的速度分為兩種,下載速度和執(zhí)行速度。要想JavaScript的下載速度快,就需要盡量減少JavaScript文件的大小,另外,把多個JavaScript文件合并成一個也能減少服務(wù)器的響應(yīng)次數(shù)而加快網(wǎng)頁下載。
可以通過對javascript的變量名稱和過程名稱進行編碼,從而起到混淆JavaScript代碼的作用,保護您的勞動成果。
其實高強度壓縮就是很好的混淆,如將變量名稱都換成a,b,c等沒有意義的字符。
2.8.1、在線壓縮與混淆
網(wǎng)絡(luò)中有很多提供在線壓縮的工具,如果僅是少量,臨時的壓縮在線壓縮與混淆是非常方便的,如:
可以搜索“javascript在線壓縮”就會有很多網(wǎng)站提供在線,免費的服務(wù)。
2.8.2、工具壓縮與混淆
可以使用GUI工具也可以使用命令行,GUI工具操作非常簡單,這里主要講基于node.js的工具UglifyJS的使用。?
UglifyJS是UglifyJS2的前身,是一個Javascript開發(fā)的通用的語法分析、代碼壓縮、代碼優(yōu)化的一個工具包。UglifyJS是基于Nodejs環(huán)境開發(fā),支持CommonJS模塊系統(tǒng)的任意的Javascript平臺。
UglifyJS2的安裝:
npm install uglify-js -g合并壓縮:
uglifyjs a.js b.js c.js -o d.js將a.js、b.js與c.js文件合并后壓縮到d.js中
混淆:
在原參數(shù)上增加-m可以將變量名稱替換成a,b,c等沒有意義的變量。
壓縮的辦法有多個還可以使用IDE中的插件:
命令參數(shù)詳細:
–source-map [string],生成source map文件。 –source-map-root [string], 指定生成source map的源文件位置。 –source-map-url [string], 指定source map的網(wǎng)站訪問地址。 –source-map-include-sources,設(shè)置源文件被包含到source map中。 –in-source-map,自定義source map,用于其他工具生成的source map。 –screw-ie8, 用于生成完全兼容IE6-8的代碼。 –expr, 解析一個表達式或JSON。 -p, –prefix [string], 跳過原始文件名的前綴部分,用于指定源文件、source map和輸出文件的相對路徑。 -o, –output [string], 輸出到文件。 -b, –beautify [string], 輸出帶格式化的文件。 -m, –mangle [string], 輸出變量名替換后的文件。 -r, –reserved [string], 保留變量名,排除mangle過程。 -c, –compress [string], 輸出壓縮后的文件。 -d, –define [string], 全局定義。 -e, –enclose [string], 把所有代碼合并到一個函數(shù)中,并提供一個可配置的參數(shù)列表。 –comments [string], 增加注釋參數(shù),如@license、@preserve。 –preamble [string], 增加注釋描述。 –stats, 顯示運行狀態(tài)。 –acorn, 用Acorn做解析。 –spidermonkey, 解析SpiderMonkey格式的文件,如JSON。 –self, 把UglifyJS2做為依賴庫一起打包。 –wrap, 把所有代碼合并到一個函數(shù)中。 –export-all, 和–wrap一起使用,自動輸出到全局環(huán)境。 –lint, 顯示環(huán)境的異常信息。 -v, –verbose, 打印運行日志詳細。 -V, –version, 打印版本號。 –noerr, 忽略錯誤命令行參數(shù)。2.9、發(fā)布插件
2.9.1、將插件發(fā)布到GitHub上
首先你需要將插件代碼放到GitHub上創(chuàng)建一個Service Hook,這樣做的目的是你以后更新的插件后,jQuery可以自動去獲取新版本的信息然后展示在插件中心的頁面上。
先在github上創(chuàng)建一個倉庫:
將插件提交到GitHub中:
2)、制作清單文件
然后需要制作一個JSON格式的清單文件,其中包括關(guān)于插件的基本信息,具體格式及參數(shù)可以在jQuery官網(wǎng)插件發(fā)布指南頁面了解到,這里提供一個示例文件,是我之前寫的一個jQuery插件SlipHover
這里參考jQuery官網(wǎng)的設(shè)置指南:http://plugins.jquery.com/docs/publish/
The jQuery Plugins Registry will look in the root level of your repository for any files named?*.jquery.json. You will want to create?*yourplugin*.jquery.json?according to the?package manifest specification. Use an online JSON verifier such as?JSONlint?to make sure the file is valid. You are now ready to publish your plugin!
在插件項目的根目錄下添加一個名稱為“插件名.jquery.json”的清單文件;清單文件可以參考package manifest specification,清單文件是一個json格式的文件,編寫好之后可以使用JSONlint驗證格式,確保沒有錯誤。
SuperPlus.jquery.json
{"name": "SuperPlus","title": "jQuery SuperPlus","description": "jQuery plugin for HTML Element.","keywords": ["super","plus","element"],"version": "1.0.0","author": {"name": "South IT College class NO1 of UED","url": "https://github.com/zhangguo5/SuperPlus/blob/master/AUTHORS.txt"},"maintainers": [{"name": "South IT College class NO1 of UED","email": "2676656856@qq.com","url": "http://best.cnblogs.com"}],"licenses": [{"type": "MIT","url": "https://github.com/jquery/jquery-color/blob/2.1.2/MIT-LICENSE.txt"}],"bugs": "https://github.com/zhangguo5/SuperPlus/issues","homepage": "https://github.com/zhangguo5/SuperPlus","docs": "https://github.com/zhangguo5/SuperPlus","download": "https://github.com/zhangguo5/SuperPlus/tree/master/dest","dependencies": {"jquery": ">=1.5"} }編輯完成清單文件可以在線驗證:
2.9.2、GitHub Service Hook
1)、在項目的根目錄下,點擊右上角的設(shè)置“settings”->"Integrations&services"
2)、在Add Service中輸入jQuery Plugin
接下來會提示登錄,輸入密碼,登錄成功后激活就完成。
搜索:
練習(xí):
請打造一個屬于自己的jQuery插件,并發(fā)布到github中,寫出使用的幫助說明。插件類型可以是:彈出層、分頁控件、驗證、圖片輪播、組織結(jié)構(gòu)圖、超級下拉列表、圖表、工具庫等。
彈出層參考:
http://www.jq22.com/yanshi10917
http://www.jq22.com/jquery-info10177
http://www.jq22.com/jquery-plugins%E5%BC%B9%E5%87%BA%E5%B1%82-1-jq
分頁控件:
https://github.com/gbirke/jquery_pagination
簡單參考:
<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>jQuery插件</title><style type="text/css">.pager {width: 800px;margin: 0 auto;}.pager .pageItem {display: inline-block;padding: 5px 8px;background: dodgerblue;margin: 3px;}.pager a {color: white;text-decoration: none;}.pager a:hover {background: orangered;}</style></head><body><div id="div1"></div><div id="div2"></div><div id="div3"></div><script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script><script src="js/SuperPlus/jQuery.SuperPlus-1.0.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript">$.fn.superPager = function(options) {var settings = {total: 100,record: 10,callback: null};$.extend(settings, options);var pager = $("<div/>").addClass("pager").appendTo(this);for(var i = 1; i <= Math.ceil(settings.total / settings.record); i++) {$("<a href='#'/>").html(i).addClass("pageItem").click(function(p) {return function() {if(settings.callback) {settings.callback(settings, p);}return false;};}(i)).appendTo(pager);}return this;}$("#div1").superPager({callback: function(opt, index) {alert(opt.total + "," + opt.record + "," + index);}});$("#div2").superPager({total:300,record:20,callback: function(opt, index) {alert(opt.total + "," + opt.record + "," + index);}});$("#div3").superPager({total:10,record:2,callback: function(opt, index) {alert(opt.total + "," + opt.record + "," + index);}});</script></body></html> View Code?
驗證:
https://jqueryvalidation.org/
http://www.jq22.com/jquery-plugins%E9%AA%8C%E8%AF%81-1-jq
<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>jQuery插件</title><style type="text/css">.error {color: red;}</style></head><body><form action="" method="post" id="form1"><p>名稱:<input type="text" required="required" data-regex="^[\u4e00-\u9fa5]{2,10}$" data-regexmsg="只允許輸入2-10位的中文" data-msg="名稱必須填寫"/></p><p>價格:<input type="text" required="required" data-regex="^\d{1,5}$"/></p><p>詳細:<input type="text" required="required" /></p><input type="submit" value="提交" /></form><script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript">$.fn.superVerify = function() {this.find("[required=required]").each(function(index, obj) {var msg = $(this).data("msg") || "請?zhí)顚懺撟侄?/span>";var fun=function(){$(this).next("span.error").remove();if(!$(this).val()){$("<span/>").html(msg).addClass("error").insertAfter(this);}}$(this).change(fun).focus(fun).blur(fun);});this.find("[data-regex]").each(function(index, obj) {var msg = $(obj).data("regexmsg") || "格式錯誤";var fun=function(){$(obj).next("span.error").remove();var exp=new RegExp($(obj).data("regex"));console.log(exp+","+$(obj).data("regex"));console.log(exp.test($(this).val()));console.log($(this).val());if($(this).val()&&!exp.test($(this).val())){$("<span/>").html(msg).addClass("error").insertAfter(this);}}$(this).change(fun).focus(fun).blur(fun);});return this;}$("#form1").superVerify();//var reg=new RegExp("^\\d{1,5}$");//alert(reg.test("123123"));</script></body></html> View Code?
圖片輪播:
比如:
<div id="adv"><a href="x.html"><img src="p1.jpg"/></a><a href="y.html"><img src="p2.jpg"/></a><a href="z.html"><img src="p3.jpg"/></a></div> $("#adv").superSwaper({speed:3000});?
超級下拉列表
$("#select1").superSelect(["中國","美國","日本"]);?
$("#select1").superSelect({data:[{"text":"中國","value":"01"},{"text":"美國","value":"02"},{"text":"日本 ","value":"03"}]});?
$("#select1").superSelect({url:"service/getAllCountry.do","text":"text","value":"id"});
$("#select1").superSelect({data:"省"});
$("#select1").superSelect({data:"學(xué)歷"});
$("#select1").superSelect({data:"性別"});
http://www.jq22.com/
三、示例下載
https://github.com/zhangguo5/javascript004.git
參照:http://www.cnblogs.com/best
轉(zhuǎn)載于:https://www.cnblogs.com/SeeYouBug/p/6246670.html
總結(jié)
以上是生活随笔為你收集整理的JavaScript学习笔记(四)——jQuery插件开发与发布的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软测管理工具实践-01
- 下一篇: 笔记之_java整理JavaScript