Home>

dropload.js provides the most basic page-up and page-up,Pull-down refresh function.It is basically common for all cases where the server returns all the data at once.

However, the demand is often not that the server returns all the data at once,Often support server-side paging,Search, sort, multi-condition filtering, etc.(Compared to the interface of Meituan cuisine)

First, the solution

Improvement 1:Due to pagination,Search, sort, multi-condition filtering,May not need to pull up,There is no data when you enter the page.

For example:search for a name that does not exist on the server.

So, add interface settings to sethasdata.

mydropload.prototype.sethasdata=function (ishasdata) {
  var me=this;
  if (ishasdata) {
   me.isdata=true;
   me. $domdown.html (me.opts.domdown.domrefresh);
   fnrecovercontentheight (me);
  } else {
   me.isdata=false;
   me. $domdown.html (me.opts.domdown.domnodata);
   fnrecovercontentheight (me);
  }
 };

Improvement 2:The above problem also caused a bug, choose different filter conditions,Then pull up to load more,There was no response at this time.

The reasons are more complicated.Example:choose different filters,The amount of data is different,If resetload is not performed, there is a problem with the calculation distance of the page's pull-up.

1. Just send the api to the server,Regardless of the return success or failure,Both must execute resetload. When successful, you need to resetload after loading all the newly added data.

2. Change the resetload as follows, add a method to call the calculated screen size.

mydropload.prototype.resetload=function () {
  var me=this;
  if (me.direction == "down" && me.upinsertdom) {
   me. $domup.css ({"height":"0"}). on ("webkittransitionend moztransitionend transitionend", function () {
    me.loading=false;
    me.upinsertdom=false;
    $(this) .remove ();
    fnrecovercontentheight (me);
   });
  } else if (me.direction == "up") {
   me.loading=false;
   if (me.isdata) {
    me. $domdown.html (me.opts.domdown.domrefresh);
    fnrecovercontentheight (me);
   } else {
    me. $domdown.html (me.opts.domdown.domnodata);
   }
  }
 }

3. Solve the above two problems,Basically solved 90%of the problem, and there is another processing after sethasdata (false).(Assuming 20 counts per page)

bug:In the sieve order condition 1:20 data are returned, and 10 data is returned by pull-up load. Sethasdata (false) is set at this time. Select filter condition 2, return 20 data, pull up and load,You will be surprised to find that it can't move.

why:After sethasdata (false), the state remains in a state where there is no more data.Pull-up loading should be locked at this time,After changing your filters,Without unlocking,So it cannot be pulled up and loaded.

Solution:Every time you change your search criteria,Filter criteria,Sorting, etc.Both need to sethasdata (true).

Second, the calling methodThe overall page logic is more complicated.Explained here in its entirety.

1. Select the div to load and add a call method.

Precautions:

(1) Remember to save the returned object.

(2) The callback after pull-up loading when loaddownfn,Here you have to deal with the logic.I turn the page to send the api, add 20 to the offset in the api parameter, and then send the api.

(3) Regardless of the api return failure,Must be resetload.

Emphasize here:

The fetchdata function calls the api. Failure or success must be self.morefund.resetload ().

And when it fails, call self.morefund.resetload () directly. On success, after new data is returned,To load html dynamically with js first, execute self.morefund.resetload () after loading.

self.morefund=$("#table-fundlist"). dropload ({
 scrollarea:window, domdown:{
  domclass:"dropload-down",  domrefresh:"<div><img src =" images/dropload_up.png "><span>pull-up load more</span>
  domload:"<div><img src =" images/droploading.gif "></div>",  domnodata:""
 }, loaddownfn:function () {
  self.apiparams.offset +=20;
  self.fetchdata (true);
 }
});

2. sethasdata

(1) When do you need to set true.

When the non-page turning API is triggered.Select a new filter.Select a new search field,Select the new sort field.You must sethasdata (true) at this time.

this.morefund.sethasdata (true);

(2) When is false set?

After the server returns the data,Compare the number of entries returned by the server with the number of entries sent by the api,Sethasdata (false) is inconsistently set.

if (data.length<this.apiparams.count) {
 this.morefund.sethasdata (false);
 this.morefund.lock ();
}

3. Lock and unlock in detail

(1) When is the lock set?

After the server returns the data,Compare the number of entries returned by the server with the number of entries sent by the api,Inconsistently set lock ().

You need to set lock () when the current page state does not need to be pulled up. For example:the status entered in the search box.

(2) When is unlock set?

There is only one place to call.Set the unlock before sending the api.

if (self.morefund) {
 self.morefund.unlock ();
}

Third, js and css source code

js:

(function ($) {
 "use strict";
 var win=window;
 var doc=document;
 var $win=$(win);
 var $doc=$(doc);
 $.fn.dropload=function (options) {
  return new mydropload (this, options);
 };
 var mydropload=function (element, options) {
  var me=this;
  me. $element=$(element);
  me.upinsertdom=false;
  me.loading=false;
  me.islockup=false;
  me.islockdown=false;
  me.isdata=true;
  me._scrolltop=0;
  me.init (options);
 };
 mydropload.prototype.init=function (options) {
  var me=this;
  me.opts=$.extend ({}, {
   scrollarea:me. $element,   domup:{
    domclass:"dropload-up",    domrefresh:"<div><img src =" ../images/dropload_down.png "><span>drop-down refresh</span></div>",    domupdate:"<div><img src =" ../images/dropload_up.png "><span>release update</span></div>",    domload:"<div><img src =" ../images/droploading.gif "></div>"
   },   domdown:{
    domclass:"dropload-down",    domrefresh:"<div><img src =" ../images/dropload_up.png "><span>pull up load more</span></div>",    domload:"<div><img src =" ../images/droploading.gif "></div>",    domnodata:""
     //domnodata:"<div><span>no data</span></div>"
   },   distance:50, //pull distance
   threshold:"", //preload distance
   loadupfn:"", //above function
   loaddownfn:"" //function below
  }, options);
  if (me.opts.loaddownfn!="") {
   me. $element.append ("<div + me.opts.domdown.domclass +" ">" + me.opts.domdown.domrefresh + "&/div>");
   me. $domdown=$("." + me.opts.domdown.domclass);
  }
  if (me.opts.scrollarea == win) {
   me. $scrollarea=$win;
   me._scrollcontentheight=$doc.height ();
   me._scrollwindowheight=doc.documentelement.clientheight;
  } else {
   me. $scrollarea=me.opts.scrollarea;
   me._scrollcontentheight=me. $element [0] .scrollheight;
   me._scrollwindowheight=me. $element.height ();
  }
  $win.on ("resize", function () {
   if (me.opts.scrollarea == win) {
    me._scrollwindowheight=win.innerheight;
   } else {
    me._scrollwindowheight=me. $element.height ();
   }
  });
  me. $element.on ("touchstart", function (e) {
   if (! me.loading) {
    fntouches (e);
    fntouchstart (e, me);
   }
  });
  me. $element.on ("touchmove", function (e) {
   if (! me.loading) {
    fntouches (e, me);
    fntouchmove (e, me);
   }
  });
  me. $element.on ("touchend", function () {
   if (! me.loading) {
    fntouchend (me);
   }
  });
  me. $scrollarea.on ("scroll", function () {
   me._scrolltop=me. $scrollarea.scrolltop ();
   fnrecovercontentheight (me)
   if (me.opts.threshold === "") {
    me._threshold=math.floor (me. $domdown.height () * 1/3);
   } else {
    me._threshold=me.opts.threshold;
   }
   if (me.opts.loaddownfn!=""&&! me.loading&&! me.islockdown&&me._threshold!=0&&(me._scrollcontentheight-me._threshold)<= (me._scrollwindowheight + me._scrolltop) ) {
    fnloaddown ();
   }
  });
  function fnloaddown () {
   me.direction="up";
   me. $domdown.html (me.opts.domdown.domload);
   me.loading=true;
   me.opts.loaddownfn (me);
  }
 };
 function fntouches (e) {
  if (! e.touches) {
   e.touches=e.originalevent.touches;
  }
 }
 function fntouchstart (e, me) {
  me._starty=e.touches [0] .pagey;
  me.touchscrolltop=me. $scrollarea.scrolltop ();
 }
 function fntouchmove (e, me) {
  me._cury=e.touches [0] .pagey;
  me._movey=me._cury-me._starty;
  if (me._movey>0) {
   me.direction="down";
  } else if (me._movey<0) {
   me.direction="up";
  }
  var _absmovey=math.abs (me._movey);
  if (me.opts.loadupfn!=""&&me.touchscrolltop<= 0&&me.direction == "down"&&! me.islockup) {
   e.preventdefault ();
   me. $domup=$("." + me.opts.domup.domclass);
   if (! me.upinsertdom) {
    me. $element.prepend ("<div + me.opts.domup.domclass +" "></div>");
    me.upinsertdom=true;
   }
   fntransition (me. $domup, 0);
   if (_absmovey<= me.opts.distance) {
    me._offsety=_absmovey;
    me. $domup.html (me.opts.domup.domrefresh);
   } else if (_absmovey>me.opts.distance&&_absmovey<= me.opts.distance * 2) {
    me._offsety=me.opts.distance + (_absmovey-me.opts.distance) * 0.5;
    me. $domup.html (me.opts.domup.domupdate);
   } else {
    me._offsety=me.opts.distance + me.opts.distance * 0.5 + (_absmovey-me.opts.distance * 2) * 0.2;
   }
   me. $domup.css ({"height":me._offsety});
  }
 }
 //touchend
 function fntouchend (me) {
  var _absmovey=math.abs (me._movey);
  if (me.opts.loadupfn!=""&&me.touchscrolltop<= 0&&me.direction == "down"&&! me.islockup) {
   fntransition (me. $domup, 300);
   if (_absmovey>me.opts.distance) {
    me. $domup.css ({"height":me. $domup.children (). height ()});
    me. $domup.html (me.opts.domup.domload);
    me.loading=true;
    me.opts.loadupfn (me);
   } else {
    me. $domup.css ({"height":"0"}). on ("webkittransitionend transitionend", function () {
     me.upinsertdom=false;
     $(this) .remove ();
    });
   }
   me._movey=0;
  }
 }
 //Get the document height again
 function fnrecovercontentheight (me) {
  if (me.opts.scrollarea == win) {
   me._scrollcontentheight=$doc.height ();
  } else {
   me._scrollcontentheight=me. $element [0] .scrollheight;
  }
 }
 mydropload.prototype.lock=function (direction) {
  var me=this;
  if (direction === undefined) {
   if (me.direction == "up") {
    me.islockdown=true;
   } else if (me.direction == "down") {
    me.islockup=true;
   } else {
    me.islockup=true;
    me.islockdown=true;
   }
  } else if (direction == "up") {
   me.islockup=true;
  } else if (direction == "down") {
   me.islockdown=true;
  }
 };
 mydropload.prototype.unlock=function () {
  var me=this;
  me.islockup=false;
  me.islockdown=false;
 };
 mydropload.prototype.sethasdata=function (ishasdata) {
  var me=this;
  if (ishasdata) {
   me.isdata=true;
   me. $domdown.html (me.opts.domdown.domrefresh);
   fnrecovercontentheight (me);
  } else {
   me.isdata=false;
   me. $domdown.html (me.opts.domdown.domnodata);
   fnrecovercontentheight (me);
  }
 };
 mydropload.prototype.resetload=function () {
  var me=this;
  if (me.direction == "down" && me.upinsertdom) {
   me. $domup.css ({"height":"0"}). on ("webkittransitionend moztransitionend transitionend", function () {
    me.loading=false;
    me.upinsertdom=false;
    $(this) .remove ();
    fnrecovercontentheight (me);
   });
  } else if (me.direction == "up") {
   me.loading=false;
   if (me.isdata) {
    me. $domdown.html (me.opts.domdown.domrefresh);
    fnrecovercontentheight (me);
   } else {
    me. $domdown.html (me.opts.domdown.domnodata);
   }
  }
 };
 function fntransition (dom, num) {
  dom.css ({
   "-webkit-transition":"all" + num + "ms",   "transition":"all" + num + "ms"
  });
 }
}) (window.zepto || window.jquery);

css:

.dropload-up,.dropload-down {
 background-color:#f0eff5;
 position:relative;
 height:0;
 overflow:hidden;
}
.dropload-down {
 height:50px;
 border-top:1px solid #e5e5e5;
}
.dropload-refresh .drop-up-icon,.dropload-refresh .drop-down-icon,.dropload-update .drop-up-icon,.dropload-update .drop-down-icon {
 vertical-align:text-bottom;
 margin-right:3px;
 height:16px;
 width:12px;
}
.dropload-load .loading-icon {
 vertical-align:middle;
 height:20px;
 width:20px;
}
.dropload-refresh span,.dropload-update span {
 vertical-align:middle;
 line-height:18px;
 font-size:16px;
 color:#585858;
}
.dropload-nodata {
 border-bottom:1px solid #e5e5e5;
 background-color:#ffffff;
}
.dropload-nodata span {
 line-height:18px;
 font-size:14px;
 color:#999999;
}
.dropload-refresh,.dropload-update,.dropload-load,.dropload-nodata {
 position:absolute;
 width:100%;
 height:50px;
 bottom:0;
 line-height:50px;
 text-align:center;
}
.dropload-down .dropload-refresh,.dropload-down .dropload-update,.dropload-down .dropload-load {
 top:0;
 bottom:auto;
}
  • Previous Android Bluetooth communication chat for sending and receiving functions
  • Next First contact with the amazing Bootstrap grid system