jQuery插件編寫及鏈式編程模型小結

来源:http://www.cnblogs.com/w-j-web/archive/2017/01/08/6262530.html
-Advertisement-
Play Games

JQuery極大的提高了我們編寫JavaScript的效率,讓我們可以愉快的編寫代碼,做出各種特效。大多數情況下,我們都是使用別人開發的JQuery插件,今天我們就來看看如何把我們常用的功能做出JQuery插件,然後像使用jQuery那樣來操作DOM. 一、jQuery插件開發快速上手 1、jQue ...


 

   JQuery極大的提高了我們編寫JavaScript的效率,讓我們可以愉快的編寫代碼,做出各種特效。大多數情況下,我們都是使用別人開發的JQuery插件,今天我們就來看看如何把我們常用的功能做出JQuery插件,然後像使用jQuery那樣來操作DOM.

 一、jQuery插件開發快速上手

1、jQuery插件模板

關於jQuery插件的編寫,我們可以通過為jQuery.fn增加一個新的函數來編寫jQuery插件。屬性的名字就是你的插件的名字,其模板如下:

(function($){
   $.fn.myJQPlugin = function(){
      //TODO:add your code
   }
})(jQuery);

其中myJQPlugin 就是你插件的名字,Function裡面的代碼就是你插件的功能實現代碼。

 

2、與DOM交互

給插件起好名字後,下麵就可以編寫我們的代碼了,但是編寫之前,必須要說一說上下文。在插件內部的範圍中,this關鍵字指向的是jQuery對象。人們很容易誤解這一點,因為在正常使用jQuery的時候,this通常指向的是一個DOM元素。不瞭解這一點,會經常使用$又包裝了一次。

複製代碼
(function( $ ){  
$.fn.myJQPlugin = function() {  
      // 沒有必要使用$(this)  
      // $(this) 跟 $($('#element'))是一樣的   
      this.html("Hello,world");
      this.click(function(){
         this.hide(); //註意這裡的this不再指向jQuery元素,這裡的this指向當前這個function對象
      });
   };  
})( jQuery ); 
複製代碼

這裡又要提到this的指向問題,比如我們想實現一個功能,點擊DOM元素,隱藏當前元素,雖然說this指向的是jQuery對象,但是在click中,this的指向發生了變化,指向了它所在的function.所以我們在click方法裡面訪問當前元素,就要通過變數了,實現方法如下:

複製代碼
(function( $ ){  
$.fn.myJQPlugin = function() {  
      // 沒有必要使用$(this)  
      // $(this) 跟 $($('#element'))是一樣的   
      this.html("Hello,world");
      var $this = $(this);
      this.click(function(){
         $this.hide(); //註意這裡的this不再指向jQuery元素,這裡的this指向當前這個function對象
      });
   };  
})( jQuery );  
複製代碼

我們聲明$this變數來保存this對象,這樣我們需要使用當前元素時,直接使用$this就可以了。下麵我們通過一個完整的實例來測試一下:

其中html頁面的代碼如下:

複製代碼
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="jquery.js" type="text/javascript"></script>
    <script src="1.js" type="text/javascript"></script>
</head>
<body>
<div id="container" style="width:800px;height:200px; border:2px #000 solid;padding:20px;font-size:20px;">Hello,world</div>
</body>
<script type="text/javascript">
  $('#container').myJQPlugin();  
</script>
</html>
複製代碼

jQuery插件的js代碼如下:

複製代碼
(function($){
   $.fn.myJQPlugin = function(){
      this.css("color","red"); //字體顏色為紅色
      this.hide();  
      this.slideDown(200);   //先隱藏,然後通過slideDown顯示出來
      var $this = $(this);
      this.click(function(){
      $this.html("Thanks,good bye!"); //顯示信息,然後淡出
      $this.fadeOut(2000);
      });
   }
})(jQuery);
複製代碼

這個插件的功能就是首先讓元素下拉顯示,然後點擊元素時顯示再見信息,然後經過2s後淡出。這裡大家可以試試在click事件裡面使用this會怎麼樣。

 

 二、jQuery的鏈式操作

1、為什麼要用鏈式操作?

實際上鏈式操作僅僅是通過對象上的方法最後加上return this. 把對象再返回回來,對象當然可以繼續調用方法啦,所以就可以鏈式操作了。那麼,簡單實現一個:

按 Ctrl+C 複製代碼 按 Ctrl+C 複製代碼

 

一般的解釋:

節省代碼量,代碼看起來更優雅。例如如果沒有鏈式,那麼你可能需要這樣寫代碼:

document.getElementById("ele").dosomething(); 
document.getElementById("ele").dootherthing(); 

這個代碼中調用了兩次document.getElementById來獲取DOM樹的元素,這樣消耗比較大,而且要寫兩行,而鏈式只要寫一行,節省了代碼……

但我們也可以用緩存元素啊。比如:

var ele = document.getElementById("ele"); 
ele.dosomething(); 
ele.dootherthing(); 

而且兩行並沒有比一行多多少代碼,甚至相應的封裝反而使得代碼更多了。
最糟糕的是所有對象的方法返回的都是對象本身,也就是說沒有返回值,這不一定在任何環境下都適合。

 

2、那麼到底為什麼要用鏈式操作呢?

為了更好的非同步體驗Javascript是無阻塞語言,所以他不是沒阻塞,而是不能阻塞,所以他需要通過事件來驅動,非同步來完成一些本需要阻塞進程的操作。 

但是非同步編程是一種令人瘋狂的東西……運行時候是分離的倒不要緊,但是編寫代碼時候也是分離的就……

常見的非同步編程模型有哪些呢? 

(1)回調函數 :

所謂的回調函數,意指先在系統的某個地方對函數進行註冊,讓系統知道這個函數的存在,然後在以後,當某個事件發生時,再調用這個函數對事件進行響應。 

複製代碼
function fun(num, callback){ 
   if(num < 0) { 
      alert("分數不能為負,輸入錯誤!"); 
   }else if(num == 0){ 
      alert("該學生可能未參加考試!"); 
   }else { 
      alert("調用高層函數處理!"); 
      setTimeout(function(){callback();}, 1000); 
   } 
} 
複製代碼

這裡callback則是回調函數。可以發現只有當num為非負數時候callback才會調用。
但是問題,如果我們不看函數內部,我們並不知道callback會幾時調用,在什麼情況下調用,代碼間產生了一定耦合,流程上也會產生一定的混亂。

雖然回調函數是一種簡單而易於部署的實現非同步的方法,但從編程體驗來說它卻不夠好。

 

(2)鏈式非同步 :

個人覺得鏈式操作最值得稱贊的還是其解決了非同步編程模型的執行流程不清晰的問題。jQuery中$(document).ready就非常好的闡釋了這一理念。DOMContentLoaded是一個事件,在DOM並未載入前,jQuery的大部分操作都不會奏效,但jQuery的設計者並沒有把他當成事件一樣來處理,而是轉成一種“選其對象,對其操作”的思路。$選擇了document對象,ready是其方法進行操作。這樣子流程問題就非常清晰了,在鏈條越後位置的方法就越後執行。 

複製代碼
(function(){ 
   var isReady=false; //判斷onDOMReady方法是否已經被執行過 
   var readyList= [];//把需要執行的方法先暫存在這個數組裡 
   var timer;//定時器句柄 
   ready=function(fn) { 
      if (isReady ) 
         fn.call( document); 
      else 
         readyList.push( function() { return fn.call(this);}); 
      return this; 
   } 
   var onDOMReady=function(){ 
      for(var i=0;i<readyList.length;i++){ 
         readyList[i].apply(document); 
      } 
      readyList = null; 
   } 
   var bindReady = function(evt){ 
      if(isReady) return; 
         isReady=true; 
         onDOMReady.call(window); 
         if(document.removeEventListener){ 
         document.removeEventListener("DOMContentLoaded", bindReady, false); 
      } else if(document.attachEvent){ 
         document.detachEvent("onreadystatechange", bindReady); 
         if(window == window.top){ 
            clearInterval(timer); 
            timer = null; 
         } 
      } 
   }; 
   if(document.addEventListener){ 
      document.addEventListener("DOMContentLoaded", bindReady, false); 
   }else if(document.attachEvent){ 
         document.attachEvent("onreadystatechange", function(){ 
         if((/loaded|complete/).test(document.readyState)) 
            bindReady(); 
         }); 
         if(window == window.top){ 
            timer = setInterval(function(){ 
            try{ 
               isReady||document.documentElement.doScroll('left');//在IE下用能否執行doScroll判斷dom是否載入完畢
            }
            catch(e){ 
               return; 
            } 
            bindReady(); 
         },5); 
      } 
   } 
})(); 
複製代碼

上面的代碼不能用$(document).ready,而應該是window.ready。 

 

(3)Promise :

CommonJS中的非同步編程模型也延續了這一想法,每一個非同步任務返回一個Promise對象,該對象有一個then方法,允許指定回調函數。 

所以我們可以這樣寫:
f1().then(f2).then(f3);
這種方法我們無需太過關註實現,也不太需要理解非同步,只要懂得通過函數選對象,通過then進行操作,就能進行非同步編程。

 

 三、維護鏈式開發的特性

   在jQuery中,一個插件緊緊是修改收集到的元素,然後返回這個元素讓鏈條上的下一個使用。這是jQuery設計的精美之處,也是jQuery如此流行的原因之一。為了保證可鏈式,你必須返回this。如下代碼:

複製代碼
(function( $ ){  
  $.fn.resize = function( type, value ) {    
   return this.each(function() {  
      var $this = $(this);  
      if (!type || type == 'width' ) {  
         $this.width(value);  
      }  
      if ( !type || type == 'height' ) {  
         $this.height(value);  
      }  
   });  
  };  
})(jQuery); 
複製代碼

調用方法如下:

 $('div').resize('width', '600').css('color','blue'); 

 

 四、jQuery插件編寫總結

 編寫jQuery插件可以充分利用庫,將公用的函數抽象出來,“迴圈利用”。以下是簡短的總結:

  • 使用(function($){//plugin})(jQuery);來包裝你的插件
  • 不要在插件的初始範圍中重覆包裹
  • 除非你返回原始值,否則返回this指針來保證可鏈式
  • 不要用一串參數,而是使用一個對象,並且設置預設值
  • 一個插件,不要為jQuery.fn附上多個函數
  • 為你的函數,事件,數據附著到某個命名空間

 

 五、參考資料

 jQuery插件開發      http://www.cnblogs.com/playerlife/archive/2012/05/11/2495269.html

 jQuery鏈式操作如何實現以及為什麼要用鏈式操作    http://www.jb51.net/article/33342.htm

轉自:http://www.cnblogs.com/yunfeifei/

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 背景 我相信很多朋友跟我一樣,初次聽到什麼Flux, Redux, Vuex,狀態管理的時候是一臉懵逼的。因為在外面之前前端大部分開發的時候,根本沒有那麼多的概念。自從ReactJS火爆後,什麼Flux, Redux,React全家桶是一套一套接踵而來。搞的很多開發者甚是頭大。所謂的ReactJS全 ...
  • 1 掘金 新標簽預設打開,每日熱門前端內容,Github熱門star數,讓你不out 2 谷歌訪問助手 你懂的 3 react developer tools react代碼調試工具,查看state和props 4 Vue.js devtools 同上 5 WEB前端助手(FeHelper)* 百度 ...
  • 0.float與margin 兩個相鄰的浮動元素,當第一個浮動元素(不論是左浮動還是右浮動)的寬度為100%時,第二個浮動元素會被擠到下麵,通過添加負margin-right值(絕對值最少等於它自身的寬度),可以使它回到第一行。 在書寫html代碼時,我們通常的習慣根據UI樣式,從左往右來寫代碼,但 ...
  • 源於前段時候微信小程式最初火爆公測時段,把以前用 Canvas 實現的大轉盤抽獎移植成微信小程式,無奈當時小程式對 Canvas 支持不夠完善,只好降低用 CSS3 實現。雖然比不上 Canvas 繪圖的絢麗,但也總算完成了一個抽獎的 Demo,詳見: "https://github.com/giv ...
  • ▓▓▓▓▓▓ 大致介紹 看到了一個輪播圖的思路,就想的自己動手實踐一下,總體來說用jQuery實現起來簡單多了 如果對代碼中使用的方法有疑問,可以參考我的jQuery學習之路(持續更新),裡面有講解;或者你和我一樣學習jQuery不久,那你可以看看我的jQuery小案例(持續更新),互相學習! 預覽 ...
  • 將html模板放入script標簽中 使用javascript開始解析模板 ...
  • 分享一下編寫設置和獲取顏色的插件,首先我將插件的名字命名為jquery.color.js。該插件用來實現以下兩個功能1.設置元素的顏色。2.獲取元素的顏色。 先在搭建好如下編寫插件的框架: 我這裡採用jQuery.fn.extend().這種方法來編寫,代碼如下: 這個方法可裡面有一個value.參 ...
  • 目前的多個項目中都用到分頁這個功能,為了提高可復用性,我特地分離出來寫了個分頁的指令。直接貼代碼,詳情如下: index.html index.js 指令模板 page.html 指令定義page.js 效果如圖所示: ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...