Hitomi Reader Optimized Slim Navbar

MutationObserverを使用して低負荷でテキストを消去し、1行を維持する

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

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

(I already have a user script manager, let me install it!)

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.

ستحتاج إلى تثبيت إضافة مثل Stylus لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتتمكن من تثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

(لدي بالفعل مثبت أنماط للمستخدم، دعني أقم بتثبيته!)

// ==UserScript==
// @name         Hitomi Reader Optimized Slim Navbar
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  MutationObserverを使用して低負荷でテキストを消去し、1行を維持する
// @author       Your Name
// @match        https://hitomi.la/reader/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 1. スタイル注入(メディアクエリ上書きと1行固定)
    const style = document.createElement('style');
    style.innerHTML = `
        /* 画面幅に関わらず強制表示 */
        @media (max-width: 979px) {
            .nav-collapse, .nav-collapse.collapse {
                display: flex !important;
                height: 24px !important;
                overflow: visible !important;
                visibility: visible !important;
            }
            .navbar .brand { display: block !important; }
        }

        /* ナビバー全体の高さを24pxに固定 */
        .navbar, .navbar-inner, .navbar-inner .container {
            min-height: 24px !important;
            height: 24px !important;
            display: flex !important;
            flex-direction: row !important;
            flex-wrap: nowrap !important;
            align-items: center !important;
            padding: 0 5px !important;
            margin: 0 !important;
        }

        .navbar .brand {
            padding: 0 8px 0 0 !important;
            margin: 0 !important;
            font-size: 12px !important;
            line-height: 24px !important;
            float: none !important;
        }

        .nav-collapse { display: flex !important; float: none !important; }
        .navbar-nav { display: flex !important; flex-direction: row !important; margin: 0 !important; }
        .navbar-nav > li { float: none !important; }

        /* テキストを見えなくする(CSS側でも念押し) */
        .navbar-nav > li > a {
            font-size: 0 !important;
            padding: 0 4px !important;
            height: 24px !important;
            display: flex !important;
            align-items: center !important;
            text-indent: -9999px; /* テキストを画面外へ */
        }
        .navbar-nav > li > a i {
            font-size: 12px !important;
            text-indent: 0; /* アイコンは戻す */
            display: inline-block !important;
        }

        .navbar-search.pull-right {
            margin-left: 5px !important;
            display: flex !important;
            align-items: center !important;
            float: none !important;
        }

        .input-medium, select#single-page-select {
            height: 19px !important;
            line-height: 1 !important;
            padding: 0 1px !important;
            font-size: 10px !important;
            width: auto !important;
            min-width: 45px !important;
            background-color: #222 !important;
            color: #ddd !important;
            border: 1px solid #444 !important;
        }

        .btn-navbar { display: none !important; }
    `;
    document.head.appendChild(style);

    // 2. テキストノードを消去する関数
    const cleanTextNodes = () => {
        const links = document.querySelectorAll('.navbar-nav > li > a');
        links.forEach(link => {
            for (let node of link.childNodes) {
                if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== "") {
                    node.textContent = "";
                }
            }
        });
    };

    // 3. MutationObserverによる低負荷な監視
    // サイトのJSがHTMLを書き換えたときだけ cleanTextNodes を実行する
    const observer = new MutationObserver(() => {
        observer.disconnect(); // ループ防止のため一時停止
        cleanTextNodes();
        observer.observe(document.querySelector('.navbar-inner'), { childList: true, subtree: true });
    });

    // 監視開始
    const target = document.querySelector('.navbar-inner');
    if (target) {
        observer.observe(target, { childList: true, subtree: true });
    }

    // 初回実行
    cleanTextNodes();
})();