When browsing web pages on mobile phones, a function is often used. When we browse JD or Taobao, the page slides to the bottom and we see that the data is automatically loaded into the list. I didn't know how these functions were implemented before, so I simulated and implemented such functions on my PC browser. Let’s take a look at the browsing effect:
When the scrollbar scrolls to the bottom of the page, the prompt "Loading..." is displayed.
When the page has all data loaded, scrolling to the bottom of the page will prompt "The data has been loaded to the end":
The process of implementing infinite data loading is roughly as follows:
1. Scroll bars to the bottom of the page.
2. Trigger ajax loading and load the data returned by the request to the list.
How to tell if the scrollbar scrolls to the bottom of the page? We can set a rule: When the scroll height of the scroll bar is less than 20 pixels different from the height of the entire document, it is considered that the scroll bar has scrolled to the bottom of the page:
Document height - Viewport height - Scroll bar scroll height < 20
To achieve such judgment through code, we must understand which code the above heights are obtained through? You can refer to an article I wrote before, "HTML element coordinate positioning, you must master these knowledge points."
In the above judgment, I encapsulated a method:
//Detection whether the scrollbar scrolls to the bottom of the page function isScrollToPageBottom(){ //Document height var documentHeight = document.documentElement.offsetHeight; var viewPortHeight = getViewportSize().h; var scrollHeight = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; return documentHeight - viewPortHeight - scrollHeight < 20; }Once we have the judgment, we can turn on a timer and monitor it once in 900 milliseconds. If isScrollToPageBottom() returns true, call ajax to request data. If false is returned, it passes 900 milliseconds before monitoring.
The following is the core code implementation:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Infinite Pagination</title> <link rel="stylesheet" href="assets/css/index.css"/></head><body><div> <ul id="list"> </ul></div><script src="//cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script><script src="js/jquery.mockjax.js"></script><script type="text/javascript" src="js/dataMock.js"></script><script type="text/javascript"> //As an object's w and h properties, return the viewport's size function getViewportSize(w){ //Use the specified window, if there is no parameter, use the current window w = w || window; //Except for IE8 and earlier versions, other browsers can use if(w.innerWidth != null) return {w: w.innerWidth, h: w.innerHeight}; //For IE (or any browser) in standard mode var d = w.document; if(document.compatMode == "CSS1Compat") return {w: d.documentElement.clientWidth, h: d.documentElement.clientHeight}; //Return to browsers in weird mode {w: d.body.clientWidth, h: d.body.clientHeight}; } //Detection whether the scrollbar scrolls to the bottom of the page function isScrollToPageBottom(){ //Document height var documentHeight = document.documentElement.offsetHeight; var viewPortHeight = getViewportSize().h; var scrollHeight = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; return documentHeight - viewPortHeight - scrollHeight < 20; } //Product template function getGoodsTemplate(goods){ return "<li>" + "<div class='pic-wrap leftFloat'>" + "<img src='" + goods.pic + "'>" + "</div>" + "<div class='info-wrap leftFloat'>" + "<div class='info-name'><span>" + goods.name + "</span></div>" + "<div class='info-address'><span>" + goods.address +"</span></div>" + "<div class='info-bottom'>" + "<div class='info-price leftFloat'><span>¥" + goods.price + "</span></div>" + "<div class='info-star leftFloat'><span>" + goods.star + "recommended</span></div>" + "<div class='info-more leftFloat'><span>More information</span></div>" + "</div>" + "</div>" + "</li>"; } //Directly load 100 pieces of data on the list during initialization $.ajax("http://localhost:8800/loadData?sessionId=" + (+ new Date)).done(function(result){ if(result.status){ var html = ""; result.data.forEach(function(goods){ html += getGoodsTemplate(goods); }); $("#list").append(html); } }); //Loading data function loadDataDynamic(){ //First show that it is loading if( $("#loadingLi").length === 0) $("#list").append("<li id='loadingLi' class='loading'>Loading...</li>"); else{ $("#loadingLi").text("Loading...").removeClass("space"); } var loadingLi = document.getElementById("loadingLi"); loadingLi.scrollIntoView(); //Loading data, after the data is loaded, you need to remove the loading prompt var hasData = false, msg = ""; $.ajax("http://localhost:8800/loadData?sessionId=" + (+ new Date)).done(function(result){ if(result.status){ if(result.data.length > 0){ hasData = true; var html = ""; result.data.forEach(function(goods){ html += getGoodsTemplate(goods); }); $("#list").append(html); }else{ msg = "The data has been loaded to the end" } } $("#list").append(loadingLi); }).fail(function(){ msg = "Data loading failed!"; }).always(function(){ !hasData && setTimeout(function(){ $(document.body).scrollTop(document.body.scrollTop -40); }, 500); msg && $("#loadingLi").text(msg); //Relisten the scrolling setTimeout(watchScroll, 900); }); } //If the scrollbar scrolls to the bottom of the page, new data needs to be loaded, and the loading prompt is displayed function watchScroll(){ if(!isScrollToPageBottom()){ setTimeout( arguments.callee, 900); return; } loadDataDynamic(); } //Start to detect scrollbar watchScroll();</script></body></html>The data I simulated through jquery-mockjax in demo. The code is as follows:
/** * Simulation interface. */var i = 0, len = 200, addresses = ["Sichuan", "Beijing", "Shanghai", "Guangzhou", "Shenzhen", "Gansu", "Yunnan", "Zhejiang", "Qinghai", "Guizhou"];function getData(){ var size = Math.min(i + 50, len), arr = []; for(; i < size; i++){ arr.push({ name: "Apple" + (i % 10 + 1), pic: "assets/images/iphone" + (i % 10 + 1) + ".jpg", price: parseInt(Math.random() * 10000), star: parseInt(Math.random() * 1000), address: addresses[i % 10] }) } return arr;}$.mockjax({ url: 'http://localhost:8800/loadData*', responseTime: 1000, response: function(settings){ this.responseText = { status: true, data: getData() } }});The entire full demo I have uploaded to github:
https://github.com/heavis/pageLoader
Online Demo:
https://heavis.github.io/pageLoader/index.html
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.