宝哥软件园

基于h5的历史改善了ajax列表请求体验

编辑:宝哥软件园 来源:互联网 时间:2021-09-22

信息丰富的网站通常显示在页面上。当点击“下一步”时,许多网站使用动态请求来避免页面刷新。虽然大家都是ajax,但我们还是可以从一些小细节来区分好坏。一个小细节是浏览器的“后退”和“前进”键是否可以支持。本文讨论了两种方法,这样浏览器可以向前和向后,或者ajax可以返回到上一页或前进到下一页,就像重定向到新页面一样。

分页显示数据最简单的方法就是在网址后添加相当于多个页面的内容,当你点击“下一页”时,让网页重定向到第1页的新地址。比如新浪新闻网就是这样做的,把网站改了:index_1,index_2,index _ 3。但是,如果这个列表不是页面的主要部分,或者页面的其他部分有很多丰富的元素,比如图片,比如导航是一个大滑块,整个页面会急剧闪烁,很多资源都要重新加载。因此,ajax请求被用来动态改变DOM。

但是,普通的动态请求不会改变网址。当用户点击下一页或页码时,当他想返回到上一页时,他可能会点击浏览器的返回按钮,这将导致前一个网站地址而不是原始页面。比如央视的新闻网就是这样。让我们从ajax请求开始,用一个完整的案例来分析它。

做了个演示。

首先,写一个请求:

//当前var pageIndex=0是什么页面;//请求函数make request(page index){ varrequest=new xmlhttprequest();request . onreadystatechange=state change;//需要两个参数,一个是当前页面,另一个是每页的数据量。request.open('GET ','/getBook?page=' pageIndex 'limit=4,true);request . send(null);函数stateChange(){ //状态代码为4,表示已加载,请求完成if(request.readyState!==4){ return;}//请求成功,如果(请求。状态=200请求。status300 | |请求。status==304) {varbooks=JSON。解析(请求。response text);renderPage(书籍);}}}获取数据后渲染:

函数render page(books){ varbook html=' table ' ' tr ' ' th title/th ' ' th author/th ' ' th version/th ' '/tr ';for(books中的var I){ book HTMl=' tr ' ' TD ' books[I]。book _ name/' TD ' ' TD ' books[I]。作者“/TD”“TD”书籍[i]。edition '/TD ' '/tr ';} BookHTML=“/table”;book HTMl=' button previous page/button ' ' button onclick=' next page();“下一页/按钮”;var section=document . create element(' section ');section.innerHtml=bookHtmldocument.getElementById('book ')。appendChild(节);}这样一个基本的ajax请求就设置好了,然后响应“下一页”按钮:

函数nextPage(){ //将1 pageIndex添加到页面的索引中;//重发请求和页面加载make request(page index);}此时,如果您什么都不做,就无法发挥浏览器后退和前进按钮的作用。

如果你能检测到用户点击了后退和前进按钮,你可以做一些文章。H5刚刚添加了这样一个事件窗口,当用户点击两个按钮时就会触发。但是仅仅检测这个事件是不够的,还需要传递一些参数,也就是说在返回上一页的时候,需要知道该页的pageIndex。这可以通过历史的推状态方法来实现。pushState(pageIndex)保存当前页面的页面索引,然后返回到此页面获取此页面索引。推送状态的参数如下:

复制代码如下:window.history.pushstate(状态、标题、URL);

其中,state是一个对象{},用于存储当前页面的数据。标题影响不大,网址是当前页面的网址。一旦这个网址被改变,浏览器地址栏的地址也会改变。

因此,在请求下一页数据的nextPage函数中,又增加了一个步骤:

函数NextPage(){ PageIndex;make request(page index);//存储当前页面window.history.pushstate的数据({page:page index},null,window . location . href);}然后收听popstate事件:

//如果用户单击后退或前进按钮窗口. addeventlistener ('pop state ',function(event){ varpage=0;//由于第一页没有pushState,返回第一页就没有数据,所以我们要判断if(event.state!==null){ page=event . state . page;} makeRequest(第页);pageIndex=page});状态数据通过事件传入,这样就可以获得页面索引。

但是,这种实现方式存在问题。如果在第二页刷新页面,就会出现混淆,如下图:先点击下一页到第二页,然后刷新页面,第一页出现,再点击下一页,第二页出现,点击后退会出现问题。显示的仍然是第二页,而不是预期的第一页,直到您再次单击返回,它将是第一页。

从右边的工具栏可以发现,点第一次返回时得到的pageIndex仍然是1。在这种情况下,需要对历史模型进行如下分析:

可以理解为历史的操作,浏览器有一个队列存储访问记录,包括每个访问过的网站和状态数据。首先,队列的第一个指针指向page=0的位置。单击下一页时,将执行推送状态,并将一个元素插入队列。同时,这个元素的url和状态数据是通过pushState操作记录的。这里可以看到,pushState的操作最重要的作用是将元素插入到历史队列中,这样浏览器的后退按钮就不会处于灰显状态,数据也是如上所述进行存储的。当指针向后移动时,团队负责人的指针向后移动,指向page=0的位置,当指针向前移动时,指向page=1的位置。

如果页面在page=1刷新,模型如下所示:

在第2步刷新时,页面的pageIndex恢复为默认值0,因此page=0显示第一页的数据,但历史使用的队列没有改变。然后,当我单击下一页时,我将另一个元素推送到这个队列。这个队列中有两个pageIndex为1的元素,所以我必须返回两次才能返回到page=0的位置,这就是上面提到的无序。

根据上面的分析,这个实现是有问题的。一旦用户没有在页面=0的位置刷新页面,将需要多次单击后退按钮才能返回到原始页面。

因此,在刷新时,更新当前页面的状态数据,并替换队列头指针的状态数据,即当前页面的数据。方法是在初始化时替换页面:

window . history . replace state({ page : page index/*这里是0*/},null,window . location . href);所以模型变成:

但是,当用户刷新时,他们更喜欢显示当前页面,而不是返回第一页。一种解决方案是使用当前页面的window.history.state数据,这是浏览器稍后支持的。在页面初始化期间设置页面索引时,它取自历史记录。状态:

var page index=window . history . state===null?0 : window . history . state . page;safari中的history.state是从最近的pushState导入的数据,所以这个方法在chrome/firefox中有效,但是safari不起作用。

第二种方法是用h5的localStorage存储当前页码:

//页面初始化,先取当前页面,从localStorage取var page index=window . local storage . page index | | 0;函数page(){//将1添加到页面的索引中,并将其存储在localstoragewindow . local storage . page index=page index中;//重发请求和页面加载make request(page index);window . history . push state({ page : page index },null,window . location . href);} window . addeventlistener(' pop state ',function(event){ var page=0;if(event.state!==null){ page=event . state . page;} makeRequest(第页);//单击后退或前进时,需要将页面放入localstoragewindow . local storage . page index=page;});将页面上所有更改页面索引的位置同时放入本地存储。这样,在刷新页面时,就可以得到当前页面的页面索引。

以上方法都是把pageIndex放在state参数中,还有一种方法是放在第三个参数url中,也就是通过改变当前页面的URL。网址中的页面索引:

//当前var页面索引是什么页面=window . location . search . replace('?page=',' ')| |;函数nextPage(){ //将页面的索引添加到pageIndex//重发请求和页面加载make request(page index);window.history.pushState(null,null,'?page=' PageIndex);}请注意,一旦执行第8行中的pushState,当前网站的地址将会改变。

应该注意的是,虽然window.history.length返回当前队列中的元素数量,但这并不意味着历史本身就是那个队列。通过不同浏览器的历史输出:

你可以看到历史是一个数组,它的作用是让用户得到history.length,当前长度,但是填充的内容是不确定的。

除了使用历史记录,还有一种哈希方法,网易新闻使用:

//当前var页面索引是什么页面=window . location . hash . replace(' # page=',' ')| |;函数NextPage(){ MakeRequest(PageIndex);window . location . hash=' # page=' page index;} window . addeventlistener(' hashchange ',function(){ var page=window . location . hash . replace(' # page=',' ')| |;makeRequest(页面);});关于保障性,请参考caniuse网站:历史IE10及以上。hashchange有更好的可支持性,IE8和以上都支持它。

虽然hashchange有很好的支持,但是history的优势是可以传输数据。它可能在一些复杂的应用中发挥很大的作用,历史支持回溯/回溯操作。

在本文中,h5的历史改善了ajax list请求的体验,希望大家喜欢。

更多资讯
游戏推荐
更多+