程序员

一看就懂,js插件编写,以手机H5分页举例

2019-02-28  本文已影响0人  刘振宁的博客

巨大的建筑,总是由一木一石叠起来的,我们何妨做做这一木一石呢?我时常做些零碎事,就是为此。
这是对的,但是我没有说过这句话! —— 鲁迅

整理一下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


    image.png

所以现在用 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,效果一样的。

上一篇下一篇

猜你喜欢

热点阅读