Improve the ajax list request experience based on h5 history
This article mainly introduces the relevant information based on h5 history to improve the ajax list request experience. Friends who need it can refer to it
Websites with rich information are usually displayed in paging. Click "Next" page", many websites use dynamic requests to avoid page refreshes. Although everyone is ajax, you can still distinguish the pros and cons from some small details. A small detail is the ability to support the browser's "back" and "forward" keys. This article discusses two methods that allow the browser to go back and forward, or let ajax have the ability to return to the previous page or advance to the next page just like redirecting to a new page.
The simplest way to display data in paging is to add multiple page numbers after the URL, and when you click "Next Page", the web page will be redirected to the new address of page 1. For example, Sina's news network does this by changing the URL: index_1, index_2, index_3... But if this list is not the main part of the page, or there are many pictures and other rich elements in other parts of the page, for example, the navigation is a large slider, and if you use this method, the entire page will flicker violently, and many resources will have to be re- load. So use ajax request to dynamically change the DOM.
But ordinary dynamic requests will not change the URL. When the user clicks on the next page, or clicks on a few pages, and wants to return to the previous page, he may click the return button of the browser. key, this will cause the return not to the page originally viewed, but to the previous URL. For example, CCTV’s news network is like this. Let's start with the ajax request and analyze it with a complete case.
Made a demo
First, write a request:
//当前第几页 var pageIndex = 0; //请求函数 function makeRequest(pageIndex){ var request = new XMLHttpRequest(); request.onreadystatechange = stateChange; //请求传两个参数,一个是当前第几页,另一个是每页的数据条数 request.open("GET", "/getBook?page=" + pageIndex + "&limit=4", true); request.send(null); function stateChange(){ //状态码为4,表示loaded,请求完成 if(request.readyState !== 4 ){ return; } //请求成功 if(request.status >= 200 && request.status < 300 || request.status === 304){ var books = JSON.parse(request.responseText); renderPage(books); } } }
Render after getting the data:
function renderPage(books){ var bookHtml = "<table>" + " <tr>" + " <th>书名</th>" + " <th>作者</th>" + " <th>版本</th>" + " </tr>"; for(var i in books){ bookHtml += "<tr>" + " <td>" + books[i].book_name + "</td>" + " <td>" + books[i].author + "</td>" + " <td>" + books[i].edition + "</td>" + "</tr>"; } bookHtml += "</table>"; bookHtml += "<button>上一页</button>" + "<button onclick='nextPage();'>下一页</button>"; var section = document.createElement("section"); section.innerHtml = bookHtml; document.getElementById("book").appendChild(section); }
Such a basic ajax request is set up, and then responds to the "next page" button:
function nextPage(){ //将页面的index加1 pageIndex++; //重新发请求和页面加载 makeRequest(pageIndex); }
At this point, if no processing is done, the browser's return and forward buttons cannot be used. role.
If you can detect when the user clicks the back and forward buttons, you can write some articles. h5 adds such an event window.onpopstate. This event will be triggered when the user clicks those two buttons. But it is not enough to detect this event. You must also be able to pass some parameters. That is to say, when returning to the previous page, you must know the pageIndex of that page. This purpose can be achieved through the pushState method of history. pushState(pageIndex) stores the pageIndex of the current page, and then obtains the pageIndex when returning to this page. The parameters of pushState are as follows:
window.history.pushState(state, title, url);
where state is an object{}, used to store the data of the current page, and the title is not very big The role of url is the url of the current page. Once this url is changed, the address in the browser address bar will also change accordingly.
Therefore, in the nextPage function that requests the next page data, add one more step:
function nextPage(){ pageIndex++; makeRequest(pageIndex); //存放当前页面的数据 window.history.pushState({page: pageIndex}, null, window.location.href); }
Then listen to the popstate event:
//如果用户点击返回或者前进按钮 window.addEventListener("popstate", function(event){ var page = 0; //由于第一页没有pushState,所以返回到第一页的时候是没有数据的,因此得做下判断 if(event.state !== null){ page = event.state.page; } makeRequest(page); pageIndex = page; });
The state data is passed in through the event. This way you can get the pageIndex.
However, there are still problems with this implementation. If you refresh the page on the second page, confusion will occur, as shown below: First, click the next page to go to the second page. page, and then refresh the page, the first page appears, then click the next page, and the second page appears. When I click Return, a problem occurs. The second page is still displayed, not the expected first page. It is the first page until I click Return again. Page:
From the toolbar on the right, you can find that the pageIndex obtained when you click Return for the first time is still 1. For this situation, the history model needs to be analyzed, as shown below:
# can be understood as the operation of history. The browser has a queue to store access records. Including each visited URL and state data. At the beginning, the first pointer of the queue points to the position of page = 0. When the next page is clicked, pushState is executed, an element is inserted into the queue, and the url and state data of this element are recorded through the pushState operation. It can be seen here that the most important function of the pushState operation is to insert elements into the history queue so that the browser's back button is not in a grayed out state, followed by the storage of data mentioned above. When you click back, the head pointer moves back one step to point to the position of page = 0, and when you click forward, it moves forward to point to the position of page = 1.
如果在page = 1的位置刷新页面,模型是这个样子的:
在第2步刷新的时候,页面的pageIndex又恢复成默认值0,所以page = 0,显示第一页数据,但是history所用的队列并没有改变。然后再点下一页时,又给这个队列push了一个元素,这个队列就有两个pageIndex 为1的元素,所以必须得两次返回才能回到page = 0的位置,也就是上面说的错乱的情况。
根据上面的分析,这样的实现是有问题的,一但用户不是在page = 0的位置刷新页面,就会出现需要点多次返回按钮才能够回到原先的页面。
所以得在刷新的时候,把当前页的state数据更新一下,用replaceState,替换队列队首指针的数据,也就是当前页的数据。方法是页面初始化时replace一下:
window.history.replaceState({page: pageIndex /*此处为0*/}, null, window.location.href);
这样模型就变成:
但其实用户刷新的时候更希望的是还是显示当前页,而不是回到第一页。一个解决办法是用当前页的window.history.state数据,这个属性浏览器支持得比较晚。在页面初始化时设置pageIndex时就从history.state取:
var pageIndex = window.history.state === null ? 0 : window.history.state.page;
safari里面的history.state是最近执行pushState传入的数据,因此这个办法在chrome/firefox里面行得通,但是safari行不通。
第二种办法是借助h5的localStorage存放当前页数:
//页面初始化,取当前第几页先从localStorage取 var pageIndex = window.localStorage.pageIndex || 0; function nextPage(){ //将页面的index加1,同时存放在localStorage window.localStorage.pageIndex = ++pageIndex; //重新发请求和页面加载 makeRequest(pageIndex); window.history.pushState({page: pageIndex}, null, window.location.href); } window.addEventListener("popstate", function(event){ var page = 0; if(event.state !== null){ page = event.state.page; } makeRequest(page); //点击返回或前进时,需要将page放到localStorage window.localStorage.pageIndex = page; });
将页面中所有改变pageIndex的地方,同时放到localStorage。这样刷新页面的时候就可以取到当前页的pageIndex。
上面的方法都是将pageIndex放到了state参数里,还有一种方法是把它放到第三个参数url里,也就是说通过改变当前页网址的办法。pageIndex从网址里面取:
//当前第几页 var pageIndex = window.location.search.replace("?page=", "") || ; function nextPage(){ //将页面的index加 ++pageIndex; //重新发请求和页面加载 makeRequest(pageIndex); window.history.pushState(null, null, "?page=" + pageIndex); }
注意,一旦执行了第8行的pushState,当前网址的地址就会发生变化。
有一点需要注意的是,window.history.length虽然返回是的当前队列的元素个数,但不代表history本身就是那个队列,通过不同浏览器的对history[i]的输出:
可以看到history是一个数组,它的作用是让用户拿到history.length,当前的长度,但是填充的内容是不确定的。
除了使用history之外,还有借助hash的方法,网易新闻就是使用了这样的方法:
//当前第几页 var pageIndex = window.location.hash.replace("#page=", "") || ; function nextPage(){ makeRequest(pageIndex); window.location.hash = "#page=" + pageIndex; } window.addEventListener("hashchange", function(){ var page = window.location.hash.replace("#page=", "") || ; makeRequest(page); });
关于支持性,参考caniuse网站:history IE10及以上支持,hashchange的支持性较好,IE8及以上都支持。
虽然hashchange的支持性较好,但是history的优点是可以传数据。对一些复杂的应用可能会有很大的发挥作用,同时history支持back/go操作。
以上本文关于h5的history改善ajax列表请求体验,希望大家喜欢。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
The above is the detailed content of Improve the ajax list request experience based on h5 history. For more information, please follow other related articles on the PHP Chinese website!

Both Python and JavaScript's choices in development environments are important. 1) Python's development environment includes PyCharm, JupyterNotebook and Anaconda, which are suitable for data science and rapid prototyping. 2) The development environment of JavaScript includes Node.js, VSCode and Webpack, which are suitable for front-end and back-end development. Choosing the right tools according to project needs can improve development efficiency and project success rate.

Yes, the engine core of JavaScript is written in C. 1) The C language provides efficient performance and underlying control, which is suitable for the development of JavaScript engine. 2) Taking the V8 engine as an example, its core is written in C, combining the efficiency and object-oriented characteristics of C. 3) The working principle of the JavaScript engine includes parsing, compiling and execution, and the C language plays a key role in these processes.

JavaScript is at the heart of modern websites because it enhances the interactivity and dynamicity of web pages. 1) It allows to change content without refreshing the page, 2) manipulate web pages through DOMAPI, 3) support complex interactive effects such as animation and drag-and-drop, 4) optimize performance and best practices to improve user experience.

C and JavaScript achieve interoperability through WebAssembly. 1) C code is compiled into WebAssembly module and introduced into JavaScript environment to enhance computing power. 2) In game development, C handles physics engines and graphics rendering, and JavaScript is responsible for game logic and user interface.

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Linux new version
SublimeText3 Linux latest version

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.
