😁Bất ngờ về sử dụng Window History full 2, window.history.scrollRestoration,history.replaceState(ok)

https://openplanning.net/12403/javascript-history-api

Ví dụ 1;

C:\Users\Administrator\OneDrive\Desktop\demo-scroll-restoration-master\public\index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Demo Scroll Restoration</title>
    <link rel="stylesheet" href="/index.css" type="text/css" />
  </head>
  <body>
    <main>
      <h1>Demo Scroll Restoration</h1>
      <p>
        Scroll restoration allows one to change the scroll 
        position of a dynamic element on the page and then 
        refresh and have the scroll position return to where 
        it had been before the refresh.
      </p>
      <ol>
        <li>Scroll the nav</li>
        <li>Observe the scroll position</li>
        <li>Refresh</li>
        <li>Observe the same scroll position</li>
      </ol>
    </main>
    <script src="/index.js" charset="utf-8"></script>
  </body>
</html>

C:\Users\Administrator\OneDrive\Desktop\demo-scroll-restoration-master\public\index.js

const STORAGE_KEY = 'aside-scroll-position-y'
function main() {
  stupifyBrowser();
  renderAside();
  restoreScrollPosition();
  bindScrollPositionSaving();
}
function stupifyBrowser() {
  // see https://html.spec.whatwg.org/multipage/history.html#scroll-restoration-mode
  window.history.scrollRestoration = 'auto'; // auto manual
}
function bindScrollPositionSaving() {
  const aside = document.querySelector('aside')
  const handleScroll = (evt) => {
    sessionStorage.setItem(STORAGE_KEY, evt.target.scrollTop)
  }
  aside.addEventListener('scroll', handleScroll)
}
function restoreScrollPosition() {
  const aside = document.querySelector('aside')
  const y = sessionStorage.getItem(STORAGE_KEY) || 0
  aside.scrollTo(0, y)
}
function renderAside(count = 300) {
  const aside = document.createElement('aside')
  aside.setAttribute('style', 'background-color: #' + randomColor())
  const ul = document.createElement('ul')
  const frag = document.createDocumentFragment()
  for (let i = 0; i < count; ++i) {
    const li = document.createElement('li')
    li.innerText = 'Item ' + i
    frag.appendChild(li)
  }
  ul.appendChild(frag)
  aside.appendChild(ul)
  document.body.append(aside)
}
function randomColor() {
  return Math.floor(Math.random() * 16777215).toString(16)
}
window.addEventListener('load', main)

C:\Users\Administrator\OneDrive\Desktop\demo-scroll-restoration-master\public\index.css

body {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
  background: #efefef;
}
aside {
  position: fixed;
  top: 0;
  left: 0;
  height: 100%;
  overflow-y: scroll;
  width: 200px;
  background: #ababab;
  font-size: 1.25rem;
}
li {
  margin-bottom: 0.5rem;
}
main {
  margin-left: calc(200px + 2rem);
}

Sau đây là một ví dụ dùng pushState để đẩy vào history.state

Ví dụ 2:

C:\xampp\htdocs\oec\index.html

<html>
<head>
  <title>State 17</title>
  <meta charset="UTF-8">
  <meta http-equiv="pragma" content="no-cache">
  <style>
  textarea {
    width: 100%;
    margin-top: 10px;
  }
  </style>
  <script src="pushState-example.js"></script>
</head>
<body onpageshow="showHistory()">
  <h2 id="my-h2">history.pushState(..)</h2>
  <button onclick="call_pushState()">
    Call history.pushState(..)
  </button>
  <br><br>
  <button onclick="history.back()">history.back()</button>
  <button onclick="history.forward()">history.forward()</button>
  <br>
  <textarea rows="8" id="log-area"></textarea>
</body>
</html>

C:\xampp\htdocs\oec\pushState-example.js

function showHistory() {
  console.log(window.history);
  var log = document.getElementById("log-area");
  log.value = "";
  log.value += "history.length=" + history.length + "\n";
  log.value += "history.scrollRestoration=" + history.scrollRestoration + "\n";
  log.value += "history.state=" + JSON.stringify(history.state) + "\n";
}
function popstateHandler(popstateEvent) {
  console.log(popstateEvent);
  document.title = popstateEvent.state.title;
  showHistory();
}
// popstate event handler:
window.onpopstate = popstateHandler;
var number = 0;
function call_pushState() {
  number = number + 1;
  var title = "State " + number;
  var dataState = {
    empId: number,
    showProfile: true,
    title: title
  };
  window.history.pushState(dataState, title);
  document.title = title;
  // Show current History:
  showHistory();
}

Một ví dụ sử dụng history.replaceState

Vi dụ 3:

C:\xampp\htdocs\oec\native.html

<html>
<head>
  <title>HTML5 History API Demo</title>
</head>
<body>
  <textarea id="log" style="width:100%;height:400px;margin:1em;"></textarea>
  <div id="url" style="border:1px black dotted;height:1em;margin:1em;"></div>
  <div id="buttons" style="margin:1em;"></div>
  <script type="text/javascript">
      var $url = document.getElementById('url'), $log = document.getElementById('log');
      window.onpopstate = function(event) {
        var message =
          "onpopstate: "+
          "location: " + location.href + ", " +
          "data: " + JSON.stringify(event.state) +
          "\n\n"
          ;
        $url.innerHTML = location.href;
        $log.innerHTML += message;
        console.log(message);
      };
      window.onhashchange = function(event) {
        var message =
          "onhashchange: "+
          "location: " + location.href + ", "+
          "hash: " + location.hash +
          "\n\n"
          ;
        $url.innerHTML = location.href;
        $log.innerHTML += message;
        console.log(message);
      };
      // Prepare Buttons
      var
        buttons = document.getElementById('buttons'),
        scripts = [
          'history.pushState({state:1}, "State 1", "?state=1");',
          'history.pushState({state:2}, "State 2", "?state=2");',
          'history.replaceState({state:3}, "State 3", "?state=3");',
          'location.hash = Math.random();',
          'history.back();',
          'history.forward();',
          'document.location.href = document.location.href.replace(/[\#\?].*/,"");'
        ],
        buttonsHTML = ''
        ;
      // Add Buttons
      for ( var i=0,n=scripts.length; i<n; ++i ) {
        var _script = scripts[i];
        buttonsHTML +=
          '<li><button onclick=\'javascript:'+_script+'\'>'+_script+'</button></li>';
      }
      buttons.innerHTML = buttonsHTML;
  </script>
</body>
</html
  1. window.history

  2. Properties

  3. Methods

  4. history.pushState()

  5. history.replaceState()

  6. Sự kiện popstate

1- window.history

Mỗi một Tab hoặc một Frame đều có một đối tượng history của nó, và mỗi đối tượng history đều chứa một tham chiếu tới 1 đối tượng đặc biệt được gọi là "Joint Session History". Đối tượng đặc biệt này quản lý tất cả các đối tượng history của trình duyệt.Sử dụng cú pháp window.history (Hoặc đơn giản là history) để truy cập vào lịch sử của Tab hoặc Frame hiện tại.Danh sách các trang trong Lịch sử sẽ thay đổi thế nào nếu bạn đang đứng tại 1 trang trong lịch sử và nhẩy đến một trang khác không thuộc vào lịch sử.Chú ý: Nhẩy đến một trang khác không thuộc vào lịch sử nghĩa là bạn không sử dụng nút BACK, FORWARD và không gọi một trong các phương thức history.back(), history.forward(), history.go(). Bạn có thể nhẩy đến một trang mới không thuộc vào lịch sử bằng cách nhấn vào một liên kết có URL khác với URL hiện tại, hoặc nhập một URL mới và nhấn Enter,..Trước khi nhẩy đến một trang mới:Sau khi nhẩy đến trang mới:

2- Properties

history.lengthTrả về số thực thể đang được quản lý trong đối tượng lịch sử của Tab (hoặc Frame) hiện tại.history.scrollRestorationKhi bạn gọi một trong các hàm back(), forward(), go() hoặc sử dụng nút BACK, FORWARD để nhẩy đến một trang trong lịch sử. Sau khi trang lịch sử hiển thị, trình duyệt cố gắng khôi phục (restore) lại ví trí cuộn (scroll) của các thanh cuộn (scrollbar) cho trang này. Cách khôi phục phụ thuộc vào giá trị của history.scrollRestoration.history.scrollRestoration có 2 giá trị là "auto" hoặc "manual". Mặc định "auto".history.scrollRestoration = "auto"Trình duyệt sẽ làm nhiệm vụ khôi phục vị trí cuộn của các thanh cuộn cho bạn.history.scrollRestoration = "manual"Bạn phải tự xử lý việc khôi phục vị trí cuộn của các thanh cuộn. Để làm được việc này thông tin vị trí cuộn của thanh cuộn cần được lưu trữ trong mỗi thực thể của Lịch sử. Xem thêm phương thức history.pushState(..).Video dưới đây cho bạn thấy sự khác biệt của các giá trị "auto""manual":

3- Methods

Các phương thức của history:

  • go([delta])

  • back()

  • forward()

  • pushState(data,title[,url])

  • replaceState(data,title[,url])

history.go([delta])Lùi lại (back) hoặc tiến (forward) delta bước trong Lịch sử. Nếu tham số delta = 0 hoặc không được cung cấp, trình duyệt sẽ tải lại (reload) trang hiện tại. Nếu delta nằm ngoài các giá trị cho phép, trình duyệt sẽ không làm gì cả.history.back()Lùi lại (back) một bước trong Lịch sử. Nó tương đương với việc gọi phương thức history.go(-1). Nếu không có trang trước (previous page) trong Lịch sử, trình duyệt không làm gì cả.history.forward()Tiến (forward) một bước trong Lịch sử. Nó tương đương với việc gọi phương thức history.go(1). Nếu không có trang kế tiếp (next page) trong Lịch sử, trình duyệt không làm gì cả. pushState(data,title[,url])Tạo ra một thực thể (một trang) trong lịch sử.replaceState(data,title[,url])Cập nhập thực thể hiện tại trong lịch sử.

4- history.pushState()

Sử dụng hash bạn có thể tạo ra các thực thể trong lịch sử, cách này giúp bạn có được các thực thể trong lịch sử trong khi trình duyệt không cần phải tải lại (reload) trang.Hãy xem một ví dụ history với hash:

history.pushState(dataState, title [,url])Phương thức history.pushState(..) cho phép bạn tạo ra một thực thể trong lịch sử (Mà URL có thể không cần thay đổi), điều này có ích trong các ứng dụng một trang đơn nhất (Single Page).Khi người dùng nhẩy đến một thực thể (một trang) trong lịch sử, mà thực thể này được tạo ra bởi việc sử dụng phương thức history.pushState(), nó sẽ tạo ra sự kiện popstate.Các tham số:dataStateMột đối tượng lưu trữ trạng thái của thực thể. Có rất nhiều thứ bạn có thể lưu trữ trong đối tượng này, chẳng hạn vị trí cuộn của các thanh cuộn, điều này giúp bạn khôi phục lại vị trí thanh cuộn một cách thủ công,...titleTham số title chỉ có ý nghĩa như một gợi ý, các trình duyệt thường không sử dụng tham số này đề thiết lập tiêu đề cho document.urlTham số url không bắt buộc, nếu được cung cấp nó phải cùng nguồn gốc (same origin) với URL hiện tại của trang.Example:

pushState-example.js

function showHistory()  {
   console.log(window.history);
   var log = document.getElementById("log-area");
   log.value="";
   log.value +="history.length="+ history.length +"\n";
   log.value +="history.scrollRestoration="+history.scrollRestoration+"\n";
   log.value +="history.state="+ JSON.stringify(history.state)+"\n";
}

function popstateHandler(popstateEvent)  {
    console.log(popstateEvent );
    document.title = popstateEvent.state.title;
    showHistory();
}

// popstate event handler:
window.onpopstate = popstateHandler;

var number = 0;

function call_pushState()  {
    number = number + 1;
    var title = "State "+ number;

    var dataState = {
         empId : number,
         showProfile: true,
         title: title
    };

    window.history.pushState(dataState, title);
    document.title = title;

    // Show current History:
    showHistory();
}

pushState-example.html

<!DOCTYPE html>
<html>
   <head>
      <title>history.pushState()</title>
      <meta charset="UTF-8">
      <meta http-equiv="pragma" content="no-cache">

      <style>textarea {width:100%;margin-top:10px;}</style>

      <script src="pushState-example.js"></script>
      
   </head>
   <body onpageshow="showHistory()">

       <h2 id="my-h2">history.pushState(..)</h2>

      <button onclick="call_pushState()">
        Call history.pushState(..)
      </button>
      <br/><br/>

      <button onclick="history.back()">history.back()</button>
      <button onclick="history.forward()">history.forward()</button>
      <br/>

      <textarea rows="8" id="log-area"></textarea>

   </body>
</html>

 

5- history.replaceState()

history.replaceState(dataState, title [,url])Phương thức history.replaceState(..) cập nhập dữ liệu trạng thái, tiêu đề, và URL cho thực thể hiện tại trong Lịch sử.Các tham số:dataStateMột đối tượng lưu trữ trạng thái của thực thể.titleTham số title chỉ có ý nghĩa như một gợi ý, các trình duyệt thường không sử dụng tham số này đề thiết lập tiêu đề cho document.urlTham số url không bắt buộc, nếu được cung cấp nó phải cùng nguồn gốc (same origin) với URL hiện tại của trang.

6- Sự kiện popstate

Sự kiện popstate xẩy ra khi người dùng nhẩy đến một trang (một thực thể) trong lịch sử được tạo ra bởi việc sử dụng phương thức history.pushState(..) hoặc history.replaceState(..).Bạn có thể lắng nghe sự kiện popstate bằng cách thêm bộ lắng nghe sự kiện (even listener) vào cho đối tượng window.

window.addEventListener(‘popstate’. function(popstateEvent)  {
    // Do something here!
)};

Hoặc sử dụng thuộc tính (property) window.onpopstate:

window.onpopstate = function(popstateEvent). {
    // Do something here!
};
  • TODO Link?

Xem thêm các chuyên mục:

Last updated

Navigation

Lionel

@Copyright 2023