Mobile WebTool

手机网页工具:全屏切换、页面缩放

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

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

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Mobile WebTool
// @namespace    howardzhangdqs
// @version      1.0.0
// @author       HowardZhangdqs
// @description  手机网页工具:全屏切换、页面缩放
// @license      WTFPL
// @icon         https://vitejs.dev/logo.svg
// @match        *://*/*
// @run-at       document-idle
// ==/UserScript==

(function () {
  'use strict';

  const styles = ":host{all:initial;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.mwt-container{position:fixed;top:8px;left:8px;z-index:2147483647;user-select:none;-webkit-user-select:none;transition:opacity .3s}.mwt-btn{width:38px;height:38px;border-radius:10px;border:none;background:#0000008c;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 2px 8px #0000004d;transition:background .2s,transform .15s;-webkit-tap-highlight-color:transparent;padding:0;line-height:1}.mwt-btn svg{width:20px;height:20px}.mwt-btn:active{background:#000000bf;transform:scale(.92)}.mwt-menu{margin-top:6px;background:#1e1e1eeb;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-radius:10px;padding:4px 0;min-width:120px;box-shadow:0 4px 16px #0006;overflow:hidden;opacity:0;transform:translateY(-8px) scale(.95);transition:opacity .2s,transform .2s;pointer-events:none}.mwt-menu.mwt-open{opacity:1;transform:translateY(0) scale(1);pointer-events:auto}.mwt-zoom-display{padding:6px 14px;text-align:center;font-size:12px;color:#ffffff80;border-bottom:1px solid rgba(255,255,255,.08);font-variant-numeric:tabular-nums}.mwt-menu-item{display:flex;align-items:center;gap:8px;width:100%;padding:9px 14px;border:none;background:none;color:#fff;font-size:14px;cursor:pointer;text-align:left;transition:background .15s;-webkit-tap-highlight-color:transparent;font-family:inherit}.mwt-menu-item:active{background:#ffffff1a}.mwt-menu-item+.mwt-menu-item{border-top:1px solid rgba(255,255,255,.06)}.mwt-menu-icon{width:18px;height:18px;flex-shrink:0;display:flex;align-items:center;justify-content:center}.mwt-menu-icon svg{width:100%;height:100%}";
  const svgTool = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M686-132 444-376q-20 8-40.5 12t-43.5 4q-100 0-170-70t-70-170q0-36 10-68.5t28-61.5l146 146 72-72-146-146q29-18 61.5-28t68.5-10q100 0 170 70t70 170q0 23-4 43.5T584-516l244 242q12 12 12 29t-12 29l-84 84q-12 12-29 12t-29-12Zm29-85 27-27-256-256q18-20 26-46.5t8-53.5q0-60-38.5-104.5T386-758l74 74q12 12 12 28t-12 28L332-500q-12 12-28 12t-28-12l-74-74q9 57 53.5 95.5T360-440q26 0 52-8t47-25l256 256ZM472-488Z"/></svg>';
  const svgFullscreen = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M800-600v-120H680v-80h120q33 0 56.5 23.5T880-720v120h-80Zm-720 0v-120q0-33 23.5-56.5T160-800h120v80H160v120H80Zm600 440v-80h120v-120h80v120q0 33-23.5 56.5T800-160H680Zm-520 0q-33 0-56.5-23.5T80-240v-120h80v120h120v80H160Zm80-160v-320h480v320H240Zm80-80h320v-160H320v160Zm0 0v-160 160Z"/></svg>';
  const svgZoomIn = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Zm-40-60v-80h-80v-80h80v-80h80v80h80v80h-80v80h-80Z"/></svg>';
  const svgZoomOut = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400ZM280-540v-80h200v80H280Z"/></svg>';
  const svgReset = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M440-122q-121-15-200.5-105.5T160-440q0-66 26-126.5T260-672l57 57q-38 34-57.5 79T240-440q0 88 56 155.5T440-202v80Zm80 0v-80q87-16 143.5-83T720-440q0-100-70-170t-170-70h-3l44 44-56 56-140-140 140-140 56 56-44 44h3q134 0 227 93t93 227q0 121-79.5 211.5T520-122Z"/></svg>';
  const ZOOM_STEP = 10;
  const ZOOM_MIN = 30;
  const ZOOM_MAX = 200;
  const AUTO_HIDE_MS = 1e4;
  (() => {
    let currentZoom = 100;
    let menuOpen = false;
    let hideTimer;
    const host = document.createElement("div");
    host.id = "mwt-root";
    document.body.appendChild(host);
    const shadow = host.attachShadow({ mode: "closed" });
    const styleEl = document.createElement("style");
    styleEl.textContent = styles;
    shadow.appendChild(styleEl);
    const container = document.createElement("div");
    container.className = "mwt-container";
    shadow.appendChild(container);
    const btn = document.createElement("button");
    btn.className = "mwt-btn";
    btn.innerHTML = svgTool;
    container.appendChild(btn);
    const menu = document.createElement("div");
    menu.className = "mwt-menu";
    container.appendChild(menu);
    const zoomDisplay = document.createElement("div");
    zoomDisplay.className = "mwt-zoom-display";
    zoomDisplay.textContent = `${currentZoom}%`;
    menu.appendChild(zoomDisplay);
    function createMenuItem(icon, label, onClick) {
      const item = document.createElement("button");
      item.className = "mwt-menu-item";
      item.innerHTML = `<span class="mwt-menu-icon">${icon}</span><span>${label}</span>`;
      item.addEventListener("click", (e) => {
        e.stopPropagation();
        resetHideTimer();
        onClick();
      });
      menu.appendChild(item);
      return item;
    }
    const fullscreenItem = createMenuItem(svgFullscreen, "全屏", toggleFullscreen);
    createMenuItem(svgZoomIn, "放大", zoomIn);
    createMenuItem(svgZoomOut, "缩小", zoomOut);
    createMenuItem(svgReset, "重置缩放", zoomReset);
    function resetHideTimer() {
      clearTimeout(hideTimer);
      hideTimer = setTimeout(() => {
        container.style.opacity = "0";
        container.style.pointerEvents = "none";
        setTimeout(() => host.remove(), 300);
      }, AUTO_HIDE_MS);
    }
    resetHideTimer();
    function updateZoomDisplay() {
      zoomDisplay.textContent = `${currentZoom}%`;
      document.documentElement.style.zoom = `${currentZoom}%`;
    }
    function toggleFullscreen() {
      if (document.fullscreenElement) {
        document.exitFullscreen();
      } else {
        document.documentElement.requestFullscreen();
      }
      toggleMenu();
    }
    function updateFullscreenIcon() {
      fullscreenItem.querySelector(".mwt-menu-icon").innerHTML = svgFullscreen;
    }
    function zoomIn() {
      currentZoom = Math.min(currentZoom + ZOOM_STEP, ZOOM_MAX);
      updateZoomDisplay();
    }
    function zoomOut() {
      currentZoom = Math.max(currentZoom - ZOOM_STEP, ZOOM_MIN);
      updateZoomDisplay();
    }
    function zoomReset() {
      currentZoom = 100;
      updateZoomDisplay();
    }
    function toggleMenu() {
      menuOpen = !menuOpen;
      menu.classList.toggle("mwt-open", menuOpen);
    }
    btn.addEventListener("click", (e) => {
      e.stopPropagation();
      toggleMenu();
      resetHideTimer();
    });
    document.addEventListener("click", () => {
      if (menuOpen) {
        menuOpen = false;
        menu.classList.remove("mwt-open");
      }
    });
    document.addEventListener("fullscreenchange", () => {
      updateFullscreenIcon();
    });
  })();

})();