웹 프론트엔드 JS 튜토리얼 h5 기록을 기반으로 Ajax 목록 요청 환경 개선

h5 기록을 기반으로 Ajax 목록 요청 환경 개선

May 24, 2018 pm 02:47 PM
ajax history html5

이 글에서는 h5 기록을 기반으로 ajax 목록 요청 경험 개선에 대한 관련 정보를 주로 소개합니다. 필요한 친구가 참고할 수 있습니다.

풍부한 정보가 있는 웹사이트는 일반적으로 "다음 페이지"를 클릭하면 많은 웹사이트가 모두 표시됩니다. 페이지 새로 고침을 피하기 위해 동적 요청 방법을 채택하십시오. 모두가 Ajax이지만, 여전히 몇 가지 작은 세부 사항으로 장점과 단점을 구분할 수 있습니다. 작은 세부 사항은 브라우저의 "뒤로" 및 "앞으로" 키를 지원하는 기능입니다. 이 기사에서는 브라우저가 앞뒤로 이동할 수 있도록 하는 두 가지 방법, 또는 새 페이지로 리디렉션하는 것처럼 ajax가 이전 페이지로 돌아가거나 다음 페이지로 이동하는 기능을 갖도록 하는 두 가지 방법에 대해 설명합니다.

 페이징에서 데이터를 표시하는 가장 간단한 방법은 URL 뒤에 여러 페이지 번호를 추가하는 것이며, "다음 페이지"를 클릭하면 해당 웹페이지가 페이지+1의 새 주소로 리디렉션됩니다. 예를 들어 Sina의 뉴스 네트워크는 URL을 index_1, index_2, index_3...으로 변경하여 이를 수행합니다. 그러나 이 목록이 페이지의 주요 부분이 아니거나 페이지의 다른 부분에 많은 그림과 기타 풍부한 요소가 있는 경우(예: 탐색은 큰 슬라이더이며 이 방법을 사용하면 전체 페이지가 심하게 깜박이고 많은 리소스를 다시 로드해야 합니다. 따라서 ajax 요청을 사용하여 DOM을 동적으로 변경하십시오.

그러나 일반적인 동적 요청은 URL을 변경하지 않습니다. 사용자가 다음 페이지를 클릭하거나 몇 페이지를 클릭하고 이전 페이지로 돌아가고 싶을 때 브라우저의 리턴 키를 클릭할 수 있습니다. , 복귀 시 원래 봤던 페이지로 돌아가지 않고, 이전 URL로 돌아가게 됩니다. 예를 들어 CCTV의 뉴스 네트워크는 이렇습니다. Ajax 요청부터 시작하여 완전한 사례로 분석해 보겠습니다.

데모를 만들었습니다

먼저 요청을 작성하세요:

 //当前第几页
  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=&#39;nextPage();&#39;>下一页</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);

여기서 상태는 현재 페이지의 데이터를 저장하는 데 사용되는 객체입니다. 제목 제목은 그렇지 않습니다. 많은 영향을 미치며 해당 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;
  });
로그인 후 복사

상태 데이터가 이벤트를 통해 전달되므로 pageIndex를 얻을 수 있습니다. .

이 구현에는 여전히 문제가 있습니다. 두 번째 페이지에서 페이지를 새로 고치면 아래와 같이 혼란이 발생합니다. 먼저 다음 페이지를 클릭하여 두 번째 페이지로 이동한 다음 페이지를 새로 고치고, 첫 번째 페이지가 나타나고 다음 페이지를 클릭하면 두 번째 페이지가 나타납니다. 돌아가기를 클릭하면 예상한 첫 번째 페이지가 아닌 두 번째 페이지가 표시됩니다. return을 다시 클릭하세요.

오른쪽에서 처음으로 return을 클릭했을 때 얻은 pageIndex가 여전히 1인 것을 도구 모음에서 확인할 수 있습니다. 이 상황에서는 다음과 같이 기록 모델을 분석해야 합니다.

브라우저에는 방문한 각 URL 및 상태 데이터를 포함한 액세스 기록을 저장하는 대기열이 있습니다. 처음에는 큐의 첫 번째 포인터가 페이지 = 0의 위치를 ​​가리킨다. 다음 페이지를 클릭하면 pushState가 실행되고 큐에 요소가 삽입되며 이 요소의 URL과 상태 데이터가 이를 통해 기록된다. pushState 작업. 여기에서 pushState 작업의 가장 중요한 기능은 브라우저의 뒤로 버튼이 회색으로 표시되지 않도록 기록 대기열에 요소를 삽입한 다음 위에서 언급한 데이터를 저장하는 것임을 알 수 있습니다. 뒤로 클릭하면 헤드 포인터가 한 단계 뒤로 이동하여 페이지 = 0의 위치를 ​​가리키고, 앞으로 클릭하면 앞으로 이동하여 페이지 = 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列表请求体验,希望大家喜欢。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

AJAX XMLHttpRequest对象详解

编写轻量ajax组件第三篇实现

Ajax请求中async:false/true的作用分析

위 내용은 h5 기록을 기반으로 Ajax 목록 요청 환경 개선의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

HTML의 테이블 테두리 HTML의 테이블 테두리 Sep 04, 2024 pm 04:49 PM

HTML의 테이블 테두리 안내. 여기에서는 HTML의 테이블 테두리 예제를 사용하여 테이블 테두리를 정의하는 여러 가지 방법을 논의합니다.

HTML의 중첩 테이블 HTML의 중첩 테이블 Sep 04, 2024 pm 04:49 PM

HTML의 Nested Table에 대한 안내입니다. 여기에서는 각 예와 함께 테이블 내에 테이블을 만드는 방법을 설명합니다.

HTML 여백-왼쪽 HTML 여백-왼쪽 Sep 04, 2024 pm 04:48 PM

HTML 여백-왼쪽 안내. 여기에서는 HTML margin-left에 대한 간략한 개요와 코드 구현과 함께 예제를 논의합니다.

HTML 테이블 레이아웃 HTML 테이블 레이아웃 Sep 04, 2024 pm 04:54 PM

HTML 테이블 레이아웃 안내. 여기에서는 HTML 테이블 레이아웃의 값에 대해 예제 및 출력 n 세부 사항과 함께 논의합니다.

HTML 입력 자리 표시자 HTML 입력 자리 표시자 Sep 04, 2024 pm 04:54 PM

HTML 입력 자리 표시자 안내. 여기서는 코드 및 출력과 함께 HTML 입력 자리 표시자의 예를 논의합니다.

HTML 정렬 목록 HTML 정렬 목록 Sep 04, 2024 pm 04:43 PM

HTML 순서 목록에 대한 안내입니다. 여기서는 HTML Ordered 목록 및 유형에 대한 소개와 각각의 예에 대해서도 설명합니다.

HTML 온클릭 버튼 HTML 온클릭 버튼 Sep 04, 2024 pm 04:49 PM

HTML onclick 버튼에 대한 안내입니다. 여기에서는 각각의 소개, 작업, 예제 및 다양한 이벤트의 onclick 이벤트에 대해 설명합니다.

HTML에서 텍스트 이동 HTML에서 텍스트 이동 Sep 04, 2024 pm 04:45 PM

HTML에서 텍스트 이동 안내. 여기서는 Marquee 태그가 구문과 함께 작동하는 방식과 구현할 예제에 대해 소개합니다.

See all articles