一看就懂,js插件編寫,以手機H5分頁舉例

巨大的建築,總是由一木一石疊起來的,我們何妨做做這一木一石呢?我時常做些零碎事,就是爲此。
這是對的,但是我沒有說過這句話! —— 魯迅

整理一下js插件的編寫,這裏以手機端H5分頁舉例。
即一共有1000條數據,每次只加載20條,當滑到底端的時候再默認加載20條,直到將所有數據加載完成。

封裝性

將自己的代碼隔開,使其他代碼不會受到任何影響。

(function (win,$) {

})(window,$);

$是Jquery,window的作用是將自己寫的插件暴露出來,讓window可以直接調用.

組成部分

定義一個插件名,包括要傳輸的參數,即一個類的定義。

定義插件,也是要在這裏進行參數傳遞。

/***
  * 插件名,首字母大寫,可以向對待類一樣對待,如:new MobilePage()
  * @param url 要請求的地址
  * @param type get,post,put等
  * @param data 要傳輸的數據.
  * @param callcack success後要執行的函數.
  */
 var MobilePage = function (options) {
     this.url = options.url;
     this.type = options.type;
     this.data = options.data;
     this.callback = options.callcack;
     this.pageParams = {
         //對應 sql中的 limit(0,3)
         start:0,
         length:3
     };
     //當次請求的數據長度,有可能=pageParams.length ,也有可能 < pagePaarams.length(最後一頁)
     this.dataLength = this.pageParams.length;
     this.dataTotal;//記錄一下數據的總長度
 }

給插件增加方法

對插件添加方法,添加方法,要加到prototype中,這樣相當於多個對象公用一套方法(跟java中的存儲一樣).

MobilePage.prototype = {
     init:function () {

     }
 }

當然,更好的寫法是一個方法一個方法的寫,上面這種寫法會將MobilePage的prototype中已有的方法覆蓋掉.

MobilePage.prototype.init = function  {

 }

或者用JQuery的extend方法進行加載

MobilePage.prototype = $.extend(MobilePage.prototype,{
     init:function () {

     }
 });

將插件的使用暴露出來.

一般一個頁面只有一個分頁,這時候只new一次,可以提供一個對象,自動new出來,並暴露給window.

win.MobilePage = MobilePage;
win.mobilePageUtil = {
    request:function (url,type,data,callback) {
        return new MobilePage(url,type,data,callback);
    }
}

核心方法

請求方法

類似於$.ajax等.

request:function () {
         var me = this;
         me.data.pageParams = JSON.stringify(me.pageParams);
         $.ajax({
             type:me.type,
             url: me.url,
             data:me.data,
             dataType: "json",
             success: function (result) {
                 console.info(result);
                 if (result.code == 'SUCCESS') {
                     var data = result.data;
                     if (me.callback) {
                         me.callback(data);
                     }
                     //這個data應該是一個數組,求一下length
                     me.dataLength = data.length;
                     me.dataTotal = result.total;
                 }
             }
         });
}

將$.ajax封裝一下,如果成功的話,則執行回調方法。並設置自己的一些屬性,包括一共有多少數據,當前返回數據有多少條,便於分頁的設置。

下一頁方法

nextPage:function () {
   this.pageParams.start += this.dataLength;
   //調用請求方法.
   if (this.pageParams.start < this.dataTotal) {
       this.request();
   } else {
       console.info("我已經到底線了,沒有數據可加載了")
   }
},

修改start數值,判斷是否加載已完成.

增加觸發事件的方法

這裏是用的window的scroll事件,來實現,這裏有3個高度。

  1. contentH 內容的高度,也就是document的高度。
  2. viewH 屏幕的高度,也就是window的高度
  3. scrollTop 滾動的高度,當滾動到最底下的時候,理論上 contentH == viewH + scrollTop


所以現在用 contentH == viewH + scrollTop 來判斷是否滑到了最底部,假如滑到了,則觸發事件,重新從服務器端請求數據.

init:function () {
         var me = this;
         //添加下拉觸發的事件
         $(win).scroll(function () {
             var contentH = $(document).height();
             var viewH = $(this).height();
             var scrollTop = $(this).scrollTop();
             console.info("contentH:" + contentH);
             console.info("viewH:" + viewH);
             console.info("scrollTop:" + scrollTop);
             if (viewH + scrollTop == contentH) {
                 //拉到底了還拉.
                 console.info("已經拉到底了,你還拉");
                 //發起請求.
                 me.nextPage();
             }
         });
},

關於 var me = this;

因爲this經常變換,用變量記錄當時this的指向.

調用

mobilePageUtil.request({
      url: api_host + "/question/mobile/study",
      type: 'GET',
      data: {questionType: 'CHOICE'},
      callback: makeAddtionHtmls
});

由於在插件中已經將mobilePageUtil 通過 window.mobilePageUtil 暴露給了window,所以這裏可以直接使用
makeAddtionHtmls爲具體的方法,注意可以接受一個list的參數.

function makeAddtionHtmls(questionList) {
  console.info(questionList);
}

全部代碼展示

上面介紹的是思路,代碼稍有衝突,代碼以下面的爲準.

/**
 * 手機端分頁,上拉加載,用scroll事件,嵌入到App中去.
 * @author liuzhenning
 * @version 0.0.1
 * @since 0.0.1 2019/02/27
 */

//封裝成一個分頁插件,自己寫,將自己的代碼隔離開
(function (win,document,$) {
  /***
   * 插件名,首字母大寫,可以向對待類一樣對待,如:new MobilePage()
   * @param url 要請求的地址
   * @param type get,post,put等
   * @param data 要傳輸的數據.
   * @param callcack success後要執行的函數.
   */
  var MobilePage = function (options) {
      // var MobilePage = function (url,type,data,callcack) {
      //仿照$.ajax的模式,傳輸對象,便於維護,方便增加屬性
      this.url = options.url;
      this.type = options.type;
      this.data = options.data;
      this.callback = options.callback;
      this.pageParams = {
          start:0,
          length:3
      };
      //當次請求的數據長度,有可能=pageParams.length ,也有可能 < pagePaarams.length(最後一頁)
      this.dataLength = this.pageParams.length;
      this.dataTotal;//記錄一下數據的總長度
      //初始化
      this.init();
      //調一次加載數據,首頁.
      this.request();
  }

  //對插件添加方法,添加方法,要加到prototype中,這樣相當於多個對象公用一套方法(跟java中的存儲一樣).
  MobilePage.prototype = {
      init:function () {
          var me = this;
          //添加下拉觸發的事件
          $(win).scroll(function () {
              var contentH = $(document).height();
              var viewH = $(this).height();
              var scrollTop = $(this).scrollTop();
              console.info("contentH:" + contentH);
              console.info("viewH:" + viewH);
              console.info("scrollTop:" + scrollTop);
              if (viewH + scrollTop == contentH) {
                  //拉到底了還拉.
                  console.info("已經拉到底了,你還拉");
                  //發起請求.
                  me.nextPage();
              }
          });
      },
      nextPage:function () {
          this.pageParams.start += this.dataLength;
          //調用請求方法.
          if (this.pageParams.start < this.dataTotal) {
              this.request();
          } else {
              console.info("我已經到底線了,沒有數據可加載了")
          }
      },
      request:function () {
          var me = this;
          me.data.pageParams = JSON.stringify(me.pageParams);
          $.ajax({
              type:me.type,
              url: me.url,
              data:me.data,
              dataType: "json",
              success: function (result) {
                  console.info(result);
                  if (result.code == 'SUCCESS') {
                      var data = result.data;
                      if (me.callback) {
                          me.callback(data);
                      }
                      //這個data應該是一個數組,求一下length
                      me.dataLength = data.length;
                      me.dataTotal = result.total;
                  }
              }
          });
      },
      reset:function () {
          this.pageParams.start = 0;
      }
  }

  //一般一個頁面只有一個分頁,這時候只new一次,可以提供一個對象,自動new出來,並暴露給window.
  win.MobilePage = MobilePage;
  win.mobilePageUtil = {
      //只request1次,之後的request,是靠事件觸發的,也就是再request的時候,那參數直接置爲默認了,無需reset.
      request:function (options) {
          return new MobilePage(options);
      }
  }
})(window,document,$);

其他

因爲手機端,要考慮內存容量的問題,所以這裏用jquery的話會有點大,小編這裏使用的是zepto,效果一樣的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章