Greasy Fork is available in English.

调整网页字体和行间距倍数

脚本菜单可用于调整网页的字体和行间距倍数

// ==UserScript==
// @name         调整网页字体和行间距倍数
// @author       ChatGPT
// @version      6.8
// @description  脚本菜单可用于调整网页的字体和行间距倍数
// @match        *://*/*
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-end
// @namespace https://greasyfork.org/users/452911
// ==/UserScript==

(function () {
  "use strict";

  var storageKey = window.location.hostname;
  var isEnabled = GM_getValue(storageKey + "_enabled", true);
  var fontMultiplier = GM_getValue(storageKey + "_font_multiplier", 1);
  var lineHeightMultiplier = GM_getValue(storageKey + "_line_height_multiplier", 1);
  var originalSizes = {};

  function storeOriginalSizes() {
    const elements = document.querySelectorAll("*");
    elements.forEach((element) => {
      originalSizes[element] = {
        fontSize: parseFloat(getComputedStyle(element).fontSize),
        lineHeight: parseFloat(getComputedStyle(element).lineHeight),
      };
    });
  }

  function enlargeFontSizeAndLineHeight() {
    const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
    const newRootFontSize = rootFontSize * fontMultiplier;
    
    const rootLineHeight = parseFloat(getComputedStyle(document.documentElement).lineHeight);
    const newRootLineHeight = rootLineHeight * lineHeightMultiplier;

    const elementsToScale = document.querySelectorAll("*");
    elementsToScale.forEach((element) => {
      const originalSize = originalSizes[element];
      if (originalSize) {
        const fontSize = originalSize.fontSize;
        element.style.fontSize = `${(fontSize / rootFontSize) * newRootFontSize}px`;

        const lineHeight = originalSize.lineHeight;
        element.style.lineHeight = `${(lineHeight / rootLineHeight) * newRootLineHeight}px`;
      }
    });

    document.documentElement.style.fontSize = `${newRootFontSize}px`;
    document.documentElement.style.lineHeight = `${newRootLineHeight}px`;
  }

  function checkFontSizeAndLineHeight() {
    if (fontMultiplier !== 1 || lineHeightMultiplier !== 1) {
      enlargeFontSizeAndLineHeight();
    }
  }

  function applyFontSizeAndLineHeightChanges() {
    if (fontMultiplier !== 1 || lineHeightMultiplier !== 1) {
      enlargeFontSizeAndLineHeight();
      const elementsToScale = document.querySelectorAll("*");
      elementsToScale.forEach((element) => {
        const originalSize = originalSizes[element];
        if (originalSize) {
          const fontSize = originalSize.fontSize;
          element.style.fontSize = `${fontSize * fontMultiplier}px`;

          const lineHeight = originalSize.lineHeight;
          element.style.lineHeight = `${lineHeight * lineHeightMultiplier}px`;
        }
      });
    }
  }

  function observeDOMChanges() {
    const observer = new MutationObserver(() => {
      if (fontMultiplier !== 1 || lineHeightMultiplier !== 1) {
        applyFontSizeAndLineHeightChanges();
      }
    });
  
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  }

  if (isEnabled && (fontMultiplier !== 1 || lineHeightMultiplier !== 1)) {
    window.addEventListener("resize", checkFontSizeAndLineHeight);
    storeOriginalSizes();
    applyFontSizeAndLineHeightChanges();
    observeDOMChanges();
  }

  GM_registerMenuCommand(isEnabled ? "禁用字体放大" : "启用字体放大", function () {
    isEnabled = !isEnabled;
    GM_setValue(storageKey + "_enabled", isEnabled);
    if (isEnabled && (fontMultiplier !== 1 || lineHeightMultiplier !== 1)) {
      window.addEventListener("resize", checkFontSizeAndLineHeight);
      applyFontSizeAndLineHeightChanges();
      observeDOMChanges();
    } else {
      document.documentElement.style.fontSize = "";
      document.documentElement.style.lineHeight = "";
      const elementsToReset = document.querySelectorAll("*");
      elementsToReset.forEach((element) => {
        element.style.fontSize = "";
        element.style.lineHeight = "";
      });
      window.removeEventListener("resize", checkFontSizeAndLineHeight);
    }
  });

  GM_registerMenuCommand("调整字体大小", function () {
    var newFontMultiplier = prompt(
      "请输入字体大小倍数",
      fontMultiplier.toString()
    );
    if (newFontMultiplier !== null) {
      fontMultiplier = parseFloat(newFontMultiplier);
      GM_setValue(storageKey + "_font_multiplier", fontMultiplier);
      if (fontMultiplier !== 1 || lineHeightMultiplier !== 1) {
        applyFontSizeAndLineHeightChanges();
      }
    }
  });

  GM_registerMenuCommand("调整行间距", function () {
    var newLineHeightMultiplier = prompt(
      "请输入行间距倍数",
      lineHeightMultiplier.toString()
    );
    if (newLineHeightMultiplier !== null) {
      lineHeightMultiplier = parseFloat(newLineHeightMultiplier);
      GM_setValue(storageKey + "_line_height_multiplier", lineHeightMultiplier);
      if (fontMultiplier !== 1 || lineHeightMultiplier !== 1) {
        applyFontSizeAndLineHeightChanges();
      }
    }
  });

  // 监听页面刷新事件,应用字体和行间距的调整
  window.addEventListener("load", () => {
    if (fontMultiplier !== 1 || lineHeightMultiplier !== 1) {
      applyFontSizeAndLineHeightChanges();
    }
  });

})();