这篇文章主要介绍了基于h5的history改善ajax列表请求体验的相关资料,需要的朋友可以参考下
信息比较丰富的网站通常会以分页显示,在点“下一页”时,很多网站都采用了动态请求的方式,避免页面刷新。虽然大家都是ajax,但是从一些小的细节还是 可以区分优劣。一个小的细节是能否支持浏览器“后退”和“前进“键。本文讨论两种方法,让浏览器可以后退和前进,或者说让ajax就像重定向到新页面一样 拥有能够返回到上一页或者前进到下一页。
数据实现分页显示,最简单的做法是在网址后面加多个page的当数,点“下一页”时,让网页重定向到page+1的新地址。例如新浪的新闻网就 是这么做的,通过改变网址实现:index_1、index_2、index_3……。但是如果这个列表并不是页面的主体部分,或者页面的其它部分有很多 图片等丰富元素,例如导航是一个很大的slider,再使用这样的方式,整个页面会闪烁得厉害,并且很多资源得重新加载。所以使用ajax请求,动态改变 DOM。
但是普通的动态的请求不会使网址发生变化,用户点了下一页,或者点了第几页,想要返回到上一个页面时,可能会去点浏览器的返回键,这样就导致返回的时候不是返回到原先查看的页面了,而是上一个网址了。例如央视的新闻网就是这样的。下面从ajax请求开始说起,以一个完整的案例进行分析。
做了一个demo
//当前第几页
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);
}
}
}
拿到数据后进行渲染:
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);
}
这样一个基本的ajax请求就搭起来了,然后再响应“下一页”按钮:
function nextPage(){
//将页面的index加1
pageIndex++;
//重新发请求和页面加载
makeRequest(pageIndex);
}
到此,如果不做任何处理的话,就不能够发挥浏览器返回、前进按钮的作用。
如果能够检测用户点了后退、前进按钮的话,就可以做些文章。h5就是增加了这么一个事件window.onpopstate,当用户点击那两个按钮就会触 发这个事件。但是光检测到这个事件是不够的,还得能够传些参数,也就是说返回到之前那个页面的时候得知道那个页面的pageIndex。通过 history的pushState方法可以达到这个目的,pushState(pageIndex)将当前页的pageIndex存起来,再返回到这个 页面时获取到这个pageIndex。pushState的参数如下:
window.history.pushState(state, title, url);
其中state为一个object{},用来存放当前页面的数据,title标题没有多大的作用,url为当前页面的url,一旦更改了这个url,浏览器地址栏的地址也会跟着变化。
于是,在请求下一页数据的nextPage函数里面,加多一步操作:
function nextPage(){
pageIndex++;
makeRequest(pageIndex);
//存放当前页面的数据
window.history.pushState({page: pageIndex}, null, window.location.href);
}
然后监听popstate事件:
//如果用户点击返回或者前进按钮
window.addEventListener("popstate", function(event){
var page = 0;
//由于第一页没有pushState,所以返回到第一页的时候是没有数据的,因此得做下判断
if(event.state !== null){
page = event.state.page;
}
makeRequest(page);
pageIndex = page;
});
state数据通过event传进来,这样就可以得到pageIndex。
在第2步刷新的时候,页面的pageIndex又恢复成默认值0,所以page = 0,显示第一页数据,但是history所用的队列并没有改变。然后再点下一页时,又给这个队列push了一个元素,这个队列就有两个pageIndex 为1的元素,所以必须得两次返回才能回到page = 0的位置,也就是上面说的错乱的情况。
根据上面的分析,这样的实现是有问题的,一但用户不是在page = 0的位置刷新页面,就会出现需要点多次返回按钮才能够回到原先的页面。
所以得在刷新的时候,把当前页的state数据更新一下,用replaceState,替换队列队首指针的数据,也就是当前页的数据。方法是页面初始化时replace一下:
window.history.replaceState({page: pageIndex /*此处为0*
本文标题为:基于h5的history改善ajax列表请求体验
- 1 Vue - 简介 2023-10-08
- 关于 html:如何从 css 表中删除边距和填充 2022-09-21
- jsPlumb+vue创建字段映射关系 2023-10-08
- 深入浅析AjaxFileUpload实现单个文件的 Ajax 文件上传库 2022-12-15
- JS实现左侧菜单工具栏 2022-08-31
- vue keep-alive 2023-10-08
- ajax实现输入提示效果 2023-02-14
- 基于CORS实现WebApi Ajax 跨域请求解决方法 2023-02-14
- layui数据表格以及传数据方式 2022-12-13
- javascript 判断当前浏览器版本并判断ie版本 2023-08-08