教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

jQuery自定義插件開發(fā)實(shí)踐

更新時間:2018年12月07日13時17分 來源:傳智播客 瀏覽次數(shù):

# jQuery自定義插件開發(fā)實(shí)踐 ## JavaScript插件是什么?
我們寫代碼,有一個很重要的原則就是“避免重復(fù)造輪子”,我們得看一下是否需要將一部分經(jīng)常重復(fù)的代碼抽象出來,寫到一個單獨(dú)的文件中便于以后再次使用。所謂JavaScript插件就是那些已經(jīng)寫好的可以極大提高自己代碼質(zhì)量或者頁面展示效果的JavaScript文件(JavaScript代碼片段/函數(shù)),之所以叫做插件,那么就是開箱即用,或者我們只要添加一些配置參數(shù)就可以達(dá)到我們需要的結(jié)果。 ## JavaScript插件的思想 * 封裝復(fù)用 ”復(fù)用”是使用JavaScript插件的目的,“封裝”是實(shí)現(xiàn)JavaScript插件的方法 * 開箱即用 所謂“開箱即用”,指的就是插件引入到工程中之后,直接使用或者配置一些參數(shù)就可以達(dá)到我們需要的結(jié)果 * 可插拔 插件是以JavaScript文件的形式提供的,使用的時候引入JavaScript文件,不需要的時候注釋調(diào)用代碼即可,實(shí)現(xiàn)可插拔 * 易維護(hù)插件是被封裝的插件,一次封裝多處使用,需要修改或者變更的時候,可以直接修改插件本身,易于維護(hù) ## 關(guān)于jQuery插件 jQuery是一款非常優(yōu)秀的開源JavaScript框架,封裝JavaScript插件時不僅可以基于原生的JavaScript實(shí)現(xiàn),也可以更方便地基于jQuery框架實(shí)現(xiàn)。
要說jQuery最為成功的地方,筆者認(rèn)為是它的可擴(kuò)展性吸引了全球眾多的開發(fā)者為其開發(fā)插件,從而建立起了一個jQuery生態(tài)系統(tǒng)。相信讀者肯定也使用或者熟悉了不少jQuery插件,比如jQuery通知插件Noty,比如非常有名的jQuery zTree樹插件、jQuery上傳插件Uploadify、操作Cookie的jQuery-Cookie插件、還有很多其他非常炫酷的插件等等。毫不夸張地說,jQuery插件對Web應(yīng)用產(chǎn)生了重大的影響。 開發(fā)人員如果想將能力上升一個臺階,那么編寫一個屬于自己的jQuery插件是個不錯的選擇,接下來筆者會介紹如何開發(fā)自定義jQuery插件,并示例給讀者。 ## jQuery插件開發(fā)模式 所謂模式,說白了就是套路,但這種套路是前人優(yōu)秀開發(fā)經(jīng)驗(yàn)的總結(jié),學(xué)習(xí)并使用模式可以讓我們更快、更好、更優(yōu)雅的編寫、組織代碼。
jQuery提供了三種插件開發(fā)模式,基于這三種模式我們可以自定義封裝jQuery插件
三種模式如下:
* **模式一:**通過$.extend()來擴(kuò)展jQuery
* **模式二:**通過$.fn 向jQuery添加新的方法
* **模式三:**通過$.widget()應(yīng)用jQuery UI的部件工廠方式創(chuàng)建 第三種模式是用于開發(fā)jQuery高級部件的,該模式開發(fā)出來的部件帶有很多jQuery內(nèi)建的特性,比如插件的狀態(tài)等,一般使用場景下用不到這種模式,本文不再細(xì)說。
第一種模式簡單些,僅僅是在jQuery命名空間或者可以理解為在jQuery身上添加了一個靜態(tài)方法而已,所以我們調(diào)用通過\$.extend()開發(fā)的插件(添加的函數(shù))時,我們直接通過\$符號調(diào)用(\$.myFunction())而不需要選中DOM元素(\$("#id").myFunction()),注意這里的myFunction指的是你自己定義的函數(shù)名。
請看下面的例子 ```html ```
運(yùn)行結(jié)果如下:

如上就是基于\$.extend()模式自定義的一個簡單jQuery插件,這個插件給jQuery擴(kuò)展了一個sayWelcome函數(shù),然后可以通過\$直接調(diào)用。如同讀者所見,基于此模式開發(fā)一些輔助性的功能插件還是比較方便的,但這種模式?jīng)]有辦法利用jQuery強(qiáng)大選擇器帶來的便利,如果要處理DOM元素并將插件較好地運(yùn)用在所選擇的元素身上,那么還是需要使用第二種模式來開發(fā)jQuery插件,我們通常見到或者使用的插件大多也是通過這種模式開發(fā)的。
接下來,筆者基于第二種模式來開發(fā)一個自定義的jQuery高亮插件并將其命名為:jqHighlight,該插件支持在頁面某個元素內(nèi)搜索某個關(guān)鍵詞并高亮關(guān)鍵詞,高亮樣式可以重新定義(高亮字體大小、高亮背景色),支持右上角標(biāo)顯示(角標(biāo)可用于顯示解釋內(nèi)容或者錯誤詞匯所對應(yīng)的正確詞匯等),右上角標(biāo)樣式也可以重新定義。
## 示例:開發(fā)自定義jQuery高亮插件jqHighlight * **jqHighlight插件效果實(shí)現(xiàn)思路** 1)關(guān)鍵詞搜索及高亮實(shí)現(xiàn)思路遍歷對象范圍內(nèi)的各個DOM元素節(jié)點(diǎn),使用正則表達(dá)式匹配,若匹配到關(guān)鍵詞,則在關(guān)鍵詞外包裝一層標(biāo)簽,后續(xù)高亮效果的實(shí)現(xiàn)都是對標(biāo)簽的操作 2)右上角標(biāo)實(shí)現(xiàn)思路 在包裝關(guān)鍵詞的標(biāo)簽內(nèi)填充一個標(biāo)簽,通過樣式控制標(biāo)簽顯示在高亮關(guān)鍵詞的右上角 - **定義插件** jqHighlight插件實(shí)際包括兩部分:高亮和清除高亮。所以可以認(rèn)為該插件由兩個小插件組成,定義如下 ```js // 高亮 $.fn.jqHighlight = function (words, options) { // 插件實(shí)現(xiàn) }; // 清除高亮 $.fn.jqHighlightClear = function (options) { // 插件實(shí)現(xiàn) }; ``` jqHighlight可以傳入兩個參數(shù),words參數(shù)是需要搜索的關(guān)鍵詞,options是設(shè)置自定義參數(shù)的對象(后續(xù)會介紹到);jqHighlightClear主要用于清除高亮效果 - **插件中自定義參數(shù)的處理** 一般情況下,在插件內(nèi)部設(shè)置默認(rèn)參數(shù),實(shí)際使用的時候,如果傳入有自定義參數(shù)就覆蓋插件的默認(rèn)參數(shù),使用$.extend將自定義參數(shù)和默認(rèn)參數(shù)合并 ```js var settings = { className: 'highlight', // 命中關(guān)鍵詞的顯示樣式,傳入css樣式類名,可以在插件外部定義該樣式的具體屬性,比如高亮字體大小、高亮背景色 supClassName:'sup', // 右上角標(biāo)css樣式類名 caseSensitive: false, // 搜索關(guān)鍵詞時是否大小寫敏感,默認(rèn)不敏感 suptext:'' // 標(biāo)注內(nèi)容,比如搜索錯別字的時候可以在右上角標(biāo)顯示正確的字 }; // extend方法會把options中重新定義的參數(shù)覆蓋到settings中,形成新的settings $.extend(settings, options); ``` - **jqHighlight插件代碼片段一** ```js $.fn.jqHighlight = function (words, options) { var settings = { className: 'highlight', // 命中關(guān)鍵詞的顯示樣式,傳入css樣式類名,可以在插件外部定義 該樣式的具體屬性,比如高亮字體大小、高亮背景色 supClassName:'sup', // 右上角標(biāo)css樣式類名 caseSensitive: false, // 搜索關(guān)鍵詞時是否大小寫敏感,默認(rèn)不敏感 suptext:'' // 標(biāo)注內(nèi)容,比如搜索錯別字的時候可以在右上角標(biāo)顯示正確的字 }; // 使用自定義參數(shù)覆蓋默認(rèn)參數(shù) $.extend(settings, options); if (words.constructor === String) { words = [words]; } // 過濾搜索關(guān)鍵詞中的空元素 words = $.grep(words, function(word, i){ return word != ''; }); // 將搜索關(guān)鍵詞中的特殊字符轉(zhuǎn)義 words = $.map(words, function(word, i) { return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); }); if (words.length == 0) { return this; }; // 根據(jù)搜索時是否配置了大小寫敏感參數(shù)調(diào)整正則表達(dá)式 var flag = settings.caseSensitive ? "" : "i"; var pattern = "(" + words.join("|") + ")"; var re = new RegExp(pattern, flag); // 使用JavaScript正則表達(dá)式在對象范圍內(nèi)的元素中搜索關(guān)鍵詞,搜索到之后進(jìn)行高亮及右上角標(biāo)處理 return this.each(function () { // 使用第一種模式j(luò)Query.extend的方式將jqHighlight插件的核心處理邏輯封裝為了輔助插件, 見后續(xù)介紹
$.highlight(this, re,settings.className, settings.supClassName,settings.suptext); }); }; ``` - **jqHighlight插件代碼片段二** 使用第一種模式j(luò)Query.extend的方式將jqHighlight插件的核心處理邏輯封裝為了輔助插件,如下 ```js $.extend({ highlight: function (node, re, className,supClassName,suptext) { // DOM元素的節(jié)點(diǎn)屬性,3代表元素或?qū)傩灾械奈谋緝?nèi)容 if (node.nodeType === 3) { var match = node.data.match(re); if (match) { var highlight = document.createElement('span'); highlight.className = className || 'highlight'; var wordNode = node.splitText(match.index); wordNode.splitText(match[0].length); var wordClone = wordNode.cloneNode(true); highlight.appendChild(wordClone); wordNode.parentNode.replaceChild(highlight, wordNode); // 根據(jù)是否有傳入右上角標(biāo)內(nèi)容添加右上角標(biāo)顯示 if(suptext != null && $.trim(suptext).length>0) { $(highlight).css("position","relative"); $(highlight).append("" + suptext + ""); } } // 若沒有找到文本內(nèi)容,鉆取處理 } else if ((node.nodeType === 1 && node.childNodes) && !/(script|style)/i.test(node.tagName) && !(node.tagName === 'SPAN' && node.className === className)) { for (var i = 0; i < node.childNodes.length; i++) { $.highlight(node.childNodes[i],re,className,supClassName,suptext); } } } }); ``` - **jqHighlightClear插件代碼片段** 高亮效果生成以后,有時我們需要清除高亮效果,只要找到我們在做高亮效果時包裝的span標(biāo)簽,然后把span標(biāo)簽remove掉保留其中的內(nèi)容就可以了。實(shí)現(xiàn)代碼如下 ```js $.fn.jqHighlightClear = function (options) { var settings = { className: 'highlight' }; jQuery.extend(settings, options); return this.find("span." + settings.className).each(function () { var parent = this.parentNode; parent.replaceChild(this.firstChild, this); parent.normalize(); }); }; ``` **注意:**jqHighlightClear使用時需要根據(jù)情況傳入className參數(shù),這個參數(shù)應(yīng)當(dāng)和使用jqHighlight時設(shè)置的className屬性保持一致,如果默認(rèn)都默認(rèn)即可,因?yàn)槟愕捻撁嬖刂锌赡苡糜谄渌猛镜膕pan,而我們要remove的是我們包裝上去的擁有特定className的那些,remove時會右上角標(biāo)會一并清除。 - **測試代碼** **Html** ```html

黑馬程序員是傳智播客旗下高端IT教育品牌,以務(wù)實(shí)、質(zhì)量、創(chuàng)新、分享、專注、責(zé)任為核心價值觀,致力于服務(wù)各大軟件企業(yè),解決當(dāng)前軟件開發(fā)技術(shù)飛速發(fā)展,而企業(yè)招不到優(yōu)秀人才的困擾。目前,“中關(guān)村黑馬程序員訓(xùn)練營”已成長為行業(yè)“學(xué)員質(zhì)量好、課程內(nèi)容深、企業(yè)滿意”的移動開發(fā)高端訓(xùn)練基地,并被評為中關(guān)村軟件園重點(diǎn)扶持人才企業(yè)。黑馬程序員不僅著重培養(yǎng)學(xué)員的基礎(chǔ)理論知識,更注重培養(yǎng)項目實(shí)施管理能力,并密切關(guān)注技術(shù)革新,不斷引入先進(jìn)的技術(shù),研發(fā)更新技術(shù)課程,確保學(xué)員進(jìn)入企業(yè)后不僅能獨(dú)立從事開發(fā)工作,更能給企業(yè)帶來新的技術(shù)體系和理念。黑馬程序員的學(xué)員多為大學(xué)畢業(yè)后,想從事IT行業(yè),但各方面條件還不成熟的年輕人。黑馬程序員的學(xué)員篩選制度非常嚴(yán)格,包括了嚴(yán)格的技術(shù)測試、自學(xué)能力測試,還包括性格測試、壓力測試、品德測試等。百里挑一的殘酷篩選制度確保了學(xué)員質(zhì)量,并降低了企業(yè)的用人風(fēng)險。一直以來,黑馬程序員的教學(xué)研發(fā)團(tuán)隊一直致力于打造精品課程資源,不斷在產(chǎn)、學(xué)、研三個層面創(chuàng)新自己的職教理念與教學(xué)方針,并集中黑馬程序員的優(yōu)勢力量,有針對性的出版了計算機(jī)系列教材30多冊,制作了配套教學(xué)視頻數(shù)十套,并發(fā)表各類技術(shù)文章數(shù)百篇。 黑馬程序員分享的免費(fèi)視頻教程累計時長10余萬小時;率先在業(yè)內(nèi)推出免費(fèi)公開課,現(xiàn)已經(jīng)開設(shè)700多節(jié);印制現(xiàn)有學(xué)科的光盤,并且面向全國范圍內(nèi)免費(fèi)給學(xué)員發(fā)放,累計發(fā)出去的光盤數(shù)量已經(jīng)突破300萬,通過免費(fèi)提供的資源已經(jīng)影響了近5000萬IT愛好者。 黑馬程序員始終秉承“為莘莘學(xué)子改變命運(yùn)而講課,為千萬學(xué)生少走彎路而著書”的使命,以技術(shù)視角關(guān)注IT產(chǎn)業(yè)發(fā)展,以深度分享推進(jìn)產(chǎn)業(yè)技術(shù)成長,致力于弘揚(yáng)技術(shù)創(chuàng)新,倡導(dǎo)分享、開放和協(xié)作,努力打造高質(zhì)量的IT人才服務(wù)平臺。

0 分享到:
和我們在線交談!