Greasy Fork is available in English.

SPA Navigate Library

History APIフックによるSPAページ遷移検知ライブラリ。SPANavigate.on() でコールバックを登録する。

Tento skript by neměl být instalován přímo. Jedná se o knihovnu, kterou by měly jiné skripty využívat pomocí meta příkazu // @require https://update.greasyfork.org/scripts/570420/1779088/SPA%20Navigate%20Library.js

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name         SPA Navigate Library
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  History APIフックによるSPAページ遷移検知ライブラリ。SPANavigate.on() でコールバックを登録する。
// @author       ...
// @match        *://*/*
// @grant        none
// @license      MIT
// ==/UserScript==

/**
 * 使い方:
 *
 *   // @require で読み込んだ後、以下のように使う
 *
 *   SPANavigate.on(({ pathname, href }) => {
 *     console.log("遷移先:", pathname);
 *   });
 *
 *   // 登録解除
 *   const handler = ({ pathname }) => { ... };
 *   SPANavigate.on(handler);
 *   SPANavigate.off(handler);
 */

(function () {
  "use strict";

  if (window.SPANavigate) return; // 二重読み込み防止

  const _listeners = new Set();

  function _dispatch() {
    const info = { pathname: location.pathname, href: location.href };
    for (const fn of _listeners) {
      try { fn(info); } catch (e) { console.error("[SPANavigate]", e); }
    }
  }

  // pushState / replaceState をフック
  const _push = history.pushState.bind(history);
  const _replace = history.replaceState.bind(history);

  history.pushState = (...args) => { _push(...args); _dispatch(); };
  history.replaceState = (...args) => { _replace(...args); _dispatch(); };

  // ブラウザの戻る/進む
  window.addEventListener("popstate", _dispatch);

  // 初回ロード
  window.addEventListener("load", _dispatch);

  window.SPANavigate = {
    /** コールバックを登録。引数: { pathname, href } */
    on(fn) { _listeners.add(fn); },
    /** コールバックを解除 */
    off(fn) { _listeners.delete(fn); },
  };
})();