preface
H5 pull-down refresh after the implementation of traditional pull-down scenes, we went to the native APP. The scenes we met were not only full-screen pull-down refresh, but more scenes were partial elements pull-down refresh, such as list pull-down refresh operation. So HERE I am again, for such scenes, we should optimize our pullRefresh, let’s start
Results show
One is the local element list drop-down refresh effect and the other is the whole page drop-down refresh effect
The overall code
Without further ado, put the code
/ * * *@param {Object} options* const pullObj = pullRefresh(options); * pullObj.init(); Initializes the * /
const parseTime = (timestamp) = > {
const a = new Date(timestamp);
const h = a.getHours();
const s = a.getMinutes();
const double = t= > t > 9 ? t : "0" + t;
return double(h) + ":" + double(s);
}
const loadingIcon = "loading.png";
const defaultOptions = {
parEl: document.body, // Parent element (big box that doesn't move)
tarEl: "app".// Target element (sliding subbox)
pullCallback: () = > { // Valid pull-down callback, usually to get the data internally and call the Finish () method
window.location.reload(); }};export function pullRefresh(_options) {
constoptions = { ... defaultOptions, ... _options };let lastUpdateTime = new Date().getTime();
let { parEl, tarEl, pullCallback } = options;
if(typeof parEl === "string") {
parEl = document.getElementById(parEl);
}
if(typeof tarEl === "string") {
tarEl = document.getElementById(tarEl);
}
const appStyleCache = tarEl.style;
const tarElPosition = appStyleCache.position;
const parTopDistance = parEl.getBoundingClientRect().top;
if(! tarElPosition) { tarEl.style["position"] = "relative";
appStyleCache["position"] = "relative";
}
const pullTextEl = document.createElement("p");
pullTextEl.style = "width: 100%; text-align: center; position: absolute; z-index: 0; left: 0; top: -50px; font-size: 12px; line-height: 16px; color: #666; display: none;";
const loadImg = document.createElement("i");
loadImg.style = `display: inline-block; width: 15px; height: 15px; margin-right: 5px; background: url('${loadingIcon}'); background-size: 100% 100%; vertical-align: middle; animation: looprotate 2s linear infinite; `;
const loadText = document.createElement("span");
loadImg.style.opacity = 0;
// Whether a valid pull-back flag bit is executed
let refreshStatus = false;
const isQBrowser = () = > { // Qq is a browser
const ua = navigator.userAgent.toLowerCase();
return!!!!! ua.match(/mqqbrowser|qzone|qqbrowser/i);
};
const finish = () = > {
if(isQBrowser()) return;
lastUpdateTime = new Date().getTime();
loadImg.style.opacity = 0;
loadText.innerText = 'Refresh succeeded \n Last updated:${parseTime(lastUpdateTime)}`;
setTimeout(() = > {
tarEl.style["transition"] = "The transform 0.2 s";
tarEl.style["transform"] = "translate(0, 0)";
setTimeout(() = > {
pullTextEl.style["display"] = "none";
// tarEl.style = appStyleCache;
}, 400);
}, 500);
};
const init = () = > {
if(isQBrowser()) return;
tarEl.appendChild(pullTextEl);
pullTextEl.appendChild(loadImg);
pullTextEl.appendChild(loadText);
let startP, moveLen;
// Pull-down processing
const pullHandler = (moveLen) = > {
// Drop down the distance from the top of the viewport
const tarTopDistance = tarEl.getBoundingClientRect().top;
// Drop down how far the element is from the top of the parent
const toParTopDistance = tarTopDistance - parTopDistance;
// Valid drop down to do processing
if(toParTopDistance >= 0) {
if(pullTextEl.style["display"= = ="none") {
// Display the prompt text only when it is valid
pullTextEl.style["display"] = "block";
}
// Drop down effect
if(moveLen > 0 && moveLen < 50){
tarEl.style["transform"] = "translate(0, " + moveLen + "px)";
} else if(moveLen >= 50 && moveLen < 100) { // To refresh the flag, the pull-down damping increases
const _moveLen = 50 + (moveLen - 50) * 0.6;
tarEl.style["transform"] = "translate(0, " + _moveLen + "px)";
} else if(moveLen >= 100) { // When the drop exceeds 100, the drop damping increases again
const _moveLen = (50 + ( 100 - 50) *0.6) + (moveLen - 100) * 0.2;
tarEl.style["transform"] = "translate(0, " + _moveLen + "px)";
}
// Pull-down trigger
if(toParTopDistance < 55) {
loadText.innerText = 'Pull down to refresh... \n Last Updated:${parseTime(lastUpdateTime)}`;
refreshStatus = false;
} else {
loadText.innerText = 'Release immediately refresh... \n Last Updated:${parseTime(lastUpdateTime)}`;
refreshStatus = true; }}}; tarEl.addEventListener("touchstart".(e) = > {
startP = e.touches[0].pageY;
tarEl.style["transition"] = "transform 0s";
});
tarEl.addEventListener("touchmove".(e) = > {
moveLen = e.touches[0].pageY - startP;
pullHandler(moveLen);
});
tarEl.addEventListener("touchend".() = > {
// Drop down the distance from the top of the viewport
const tarTopDistance = tarEl.getBoundingClientRect().top;
// Drop down how far the element is from the top of the parent
const toParTopDistance = tarTopDistance - parTopDistance;
if(toParTopDistance > 0) { // When a valid pull-down occurs, the animation returns, resetting the style
if(refreshStatus) {
loadImg.style.opacity = 1;
loadText.innerText = 'Refreshing data... \n Last Updated:${parseTime(lastUpdateTime)}`;
pullCallback && pullCallback();
tarEl.style["transition"] = "The transform 0.4 s";
tarEl.style["transform"] = "translate(0, 55px)";
} else {
tarEl.style["transition"] = "The transform 0.4 s";
tarEl.style["transform"] = "translate(0, 0)";
setTimeout(() = > {
pullTextEl.style["display"] = "none";
tarEl.style = appStyleCache;
}, 400); }}else { // Direct reset style with no valid pull-down occurred
pullTextEl.style["display"] = "none"; tarEl.style = appStyleCache; }}); };return {
init,
finish
};
}
Copy the code
How to use
This optimization updates the input method to accept an Option object
const pullRefreshObj = pullRefresh({
parEl: "pullParEl".// Act on the parent element
tarEl: "pullTarEl".// Target action element
pullCallback: async() = > {// Generates a valid pull-down release trigger callback method
awaityourHandler(); pullRefreshObj.finish(); }}); pullRefreshObj.init();/ / initialization
Copy the code
conclusion
Yes, following the first version of the pull-down refresh, we have successfully captured the heart of the user, experience up, but also worry to keep users? Salute every front-end coder; The new one;