// ==UserScript== // @name 强制网页缩放 (解除UA/触摸限制) // @namespace https://viayoo.com/ // @version 1.2 // @description 解决迅雷浏览器等修改UA为电脑版后无法缩放的问题。强制解除网页禁止缩放限制,并提供悬浮缩放按钮。 // @author Qwen // @match *://*/* // @run-at document-start // @grant GM_addStyle // @license All Rights Reserved // ==/UserScript== (function () { 'use strict'; // ================= 1. 强制覆盖 CSS 触摸与选择限制 ================= const css = ` html, body, * { touch-action: auto !important; -ms-touch-action: auto !important; user-select: auto !important; -webkit-user-select: auto !important; } /* 确保悬浮按钮不被网页样式遮挡 */ #force-zoom-ui { touch-action: auto !important; user-select: none !important; } `; if (typeof GM_addStyle !== 'undefined') { GM_addStyle(css); } else { const style = document.createElement('style'); style.innerHTML = css; (document.head || document.documentElement).appendChild(style); } // ================= 2. 篡改 Viewport Meta 标签 ================= function fixViewport() { const metas = document.querySelectorAll('meta[name="viewport"]'); metas.forEach(meta => { let content = meta.getAttribute('content') || ''; // 替换禁止缩放的属性 content = content.replace(/user-scalable\s*=\s*no/gi, 'user-scalable=yes'); content = content.replace(/maximum-scale\s*=\s*[\d.]+/gi, 'maximum-scale=10.0'); content = content.replace(/minimum-scale\s*=\s*[\d.]+/gi, 'minimum-scale=0.1'); // 如果没有相关属性,则强制追加 if (!/user-scalable/i.test(content)) { content += ', user-scalable=yes, maximum-scale=10.0, minimum-scale=0.1'; } meta.setAttribute('content', content); }); } // ================= 3. 拦截 JS 阻止缩放的事件 ================= // 很多网站通过监听 touchstart/gesturestart 并调用 preventDefault 来禁止缩放 const blockEvents = ['touchstart', 'touchmove', 'touchend', 'gesturestart', 'gesturechange', 'gestureend']; blockEvents.forEach(eventName => { document.addEventListener(eventName, function (e) { // 如果是多指触摸(双指缩放操作),则阻止网页 JS 的拦截 if (e.touches && e.touches.length > 1) { e.stopPropagation(); } }, { passive: false, capture: true }); // capture: true 确保在网页 JS 之前执行 }); // ================= 4. 保底方案:悬浮缩放控件 ================= let currentZoom = 1.0; function applyZoom(level) { currentZoom = level; // Chrome/Chromium 内核支持 CSS zoom,这是最完美的缩放方式,不会破坏布局 document.documentElement.style.zoom = level; } function createZoomUI() { if (document.getElementById('force-zoom-ui')) return; const container = document.createElement('div'); container.id = 'force-zoom-ui'; container.style.cssText = ` position: fixed; bottom: 30px; right: 20px; z-index: 2147483647; display: flex; flex-direction: column; gap: 12px; opacity: 0.85; transition: opacity 0.3s; `; container.ontouchstart = () => container.style.opacity = '1'; container.ontouchend = () => setTimeout(() => container.style.opacity = '0.6', 2000); const btnStyle = ` width: 45px; height: 45px; border-radius: 50%; background: rgba(30, 30, 30, 0.85); color: #fff; border: 1px solid #555; font-size: 24px; display: flex; align-items: center; justify-content: center; cursor: pointer; user-select: none; box-shadow: 0 4px 10px rgba(0,0,0,0.4); backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px); `; // 放大按钮 const zoomIn = document.createElement('div'); zoomIn.innerHTML = '+'; zoomIn.style.cssText = btnStyle; zoomIn.onclick = (e) => { e.preventDefault(); applyZoom(Math.min(currentZoom + 0.2, 5.0)); }; // 缩小按钮 const zoomOut = document.createElement('div'); zoomOut.innerHTML = '-'; zoomOut.style.cssText = btnStyle; zoomOut.onclick = (e) => { e.preventDefault(); applyZoom(Math.max(currentZoom - 0.2, 0.4)); }; // 重置按钮 const zoomReset = document.createElement('div'); zoomReset.innerHTML = '↺'; zoomReset.style.cssText = btnStyle + 'font-size: 20px;'; zoomReset.onclick = (e) => { e.preventDefault(); applyZoom(1.0); }; container.appendChild(zoomIn); container.appendChild(zoomOut); container.appendChild(zoomReset); document.body.appendChild(container); } // ================= 5. 初始化与监听 ================= // 尽早执行一次 Meta 修复 fixViewport(); // 监听 DOM 变化,防止网页动态插入禁止缩放的 meta 标签 const observer = new MutationObserver(() => fixViewport()); const startObserver = () => {