美文网首页程序员
一看就懂,js插件编写,以手机H5分页举例

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

作者: 刘振宁的博客 | 来源:发表于2019-02-28 10:39 被阅读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,效果一样的。

    相关文章

      网友评论

        本文标题:一看就懂,js插件编写,以手机H5分页举例

        本文链接:https://www.haomeiwen.com/subject/gothuqtx.html