SPA Navigate Library

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

Този скрипт не може да бъде инсталиран директно. Това е библиотека за други скриптове и може да бъде използвана с мета-директива // @require https://update.greasyfork.org/scripts/570420/1779088/SPA%20Navigate%20Library.js

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==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); },
  };
})();