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