视图转换

电脑端和手机端视图切换工具

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         视图转换
// @namespace    https://viayoo.com/
// @version      1.4.1
// @description  电脑端和手机端视图切换工具
// @author       DeepSeek
// @match        *://*/*
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    class ViewConverter {
        constructor() {
            this.currentHost = window.location.hostname;
            this.isEnabled = false;
            this.settings = {
                viewMode: 'desktop',
                customViewportWidth: 375,
                desktopViewportWidth: 1200
            };
            this.menuCommands = [];
            
            this.viewportPresets = {
                '小屏设备 (320px)': 320,
                '标准手机 (375px)': 375,
                '大屏手机 (390px)': 390,
                'Google Pixel (412px)': 412,
                'iPhone Plus (414px)': 414,
                '平板设备 (768px)': 768,
                '小平板 (1024px)': 1024
            };
            
            this.init();
        }

        init() {
            this.loadSettings();
            this.createMainMenu();
            if (this.isEnabled) {
                if (document.readyState === 'loading') {
                    document.addEventListener('DOMContentLoaded', () => this.applyViewMode());
                } else {
                    this.applyViewMode();
                }
            }
        }

        loadSettings() {
            const enabledHosts = GM_getValue('enabledHosts', {});
            this.isEnabled = !!enabledHosts[this.currentHost];
            
            const hostSettings = GM_getValue(`host_${this.currentHost}`, {
                viewMode: 'desktop',
                customViewportWidth: 375,
                desktopViewportWidth: 1200
            });
            this.settings = hostSettings;
        }

        saveSettings() {
            GM_setValue(`host_${this.currentHost}`, this.settings);
        }

        enableCurrentHost() {
            const enabledHosts = GM_getValue('enabledHosts', {});
            enabledHosts[this.currentHost] = true;
            GM_setValue('enabledHosts', enabledHosts);
            this.isEnabled = true;
        }

        disableCurrentHost() {
            const enabledHosts = GM_getValue('enabledHosts', {});
            delete enabledHosts[this.currentHost];
            GM_setValue('enabledHosts', enabledHosts);
            this.isEnabled = false;
        }

        createMainMenu() {
            this.clearMenu();
            
            if (!this.isEnabled) {
                this.menuCommands.push(
                    GM_registerMenuCommand(`🚫 在当前网站启用 (${this.currentHost})`, () => this.enableScript())
                );
                return;
            }

            const currentStatus = this.getCurrentStatusText();
            const switchText = this.getSwitchText();
            
            this.menuCommands.push(
                GM_registerMenuCommand(`✅ ${currentStatus}`, () => this.showStatus()),
                GM_registerMenuCommand(switchText, () => this.toggleViewMode())
            );

            if (this.settings.viewMode === 'mobile') {
                this.menuCommands.push(
                    GM_registerMenuCommand('🎯 设置手机视口', () => this.showMobileViewportMenu())
                );
            } else {
                this.menuCommands.push(
                    GM_registerMenuCommand('🔧 设置电脑视口', () => this.showDesktopViewportMenu())
                );
            }

            this.menuCommands.push(
                GM_registerMenuCommand('❌ 禁用脚本', () => this.disableScript())
            );
        }

        clearMenu() {
            this.menuCommands.forEach(id => GM_unregisterMenuCommand(id));
            this.menuCommands = [];
        }

        getCurrentStatusText() {
            if (this.settings.viewMode === 'mobile') {
                return `手机模式: ${this.settings.customViewportWidth}px`;
            } else {
                return `电脑模式: ${this.settings.desktopViewportWidth}px`;
            }
        }

        getSwitchText() {
            return this.settings.viewMode === 'mobile' ? '💻 切换到电脑端' : '📱 切换到手机端';
        }

        enableScript() {
            this.enableCurrentHost();
            this.saveSettings();
            this.createMainMenu();
            this.applyViewMode();
            this.showNotification(`已在 ${this.currentHost} 启用脚本`);
        }

        disableScript() {
            this.removeAllStyles();
            this.resetViewport();
            this.disableCurrentHost();
            this.createMainMenu();
            this.showNotification(`已在 ${this.currentHost} 禁用脚本`);
        }

        toggleViewMode() {
            if (!this.isEnabled) return;
            
            this.settings.viewMode = this.settings.viewMode === 'mobile' ? 'desktop' : 'mobile';
            this.saveSettings();
            this.createMainMenu();
            this.applyViewMode();
            
            this.showNotification(`已切换到 ${this.settings.viewMode === 'mobile' ? '手机模式' : '电脑模式'}`);
        }

        showMobileViewportMenu() {
            if (!this.isEnabled) return;

            this.clearMenu();
            
            Object.keys(this.viewportPresets).forEach(deviceName => {
                this.menuCommands.push(
                    GM_registerMenuCommand(`📱 ${deviceName}`, () => {
                        this.setMobileViewport(this.viewportPresets[deviceName]);
                    })
                );
            });

            this.menuCommands.push(
                GM_registerMenuCommand('🔧 自定义宽度', () => this.setCustomMobileViewport()),
                GM_registerMenuCommand('↩️ 返回', () => this.createMainMenu())
            );
        }

        showDesktopViewportMenu() {
            if (!this.isEnabled) return;

            this.clearMenu();
            
            const desktopPresets = {
                '💻 笔记本 (1200px)': 1200,
                '🖥️ 标准桌面 (1366px)': 1366,
                '🖥️ 大屏桌面 (1440px)': 1440,
                '🖥️ 宽屏桌面 (1920px)': 1920
            };

            Object.keys(desktopPresets).forEach(presetName => {
                this.menuCommands.push(
                    GM_registerMenuCommand(presetName, () => {
                        this.setDesktopViewport(desktopPresets[presetName]);
                    })
                );
            });

            this.menuCommands.push(
                GM_registerMenuCommand('🔧 自定义宽度', () => this.setCustomDesktopViewport()),
                GM_registerMenuCommand('↩️ 返回', () => this.createMainMenu())
            );
        }

        setMobileViewport(width) {
            this.settings.customViewportWidth = width;
            this.settings.viewMode = 'mobile';
            this.saveSettings();
            this.applyViewMode();
            this.showNotification(`手机视口设置为 ${width}px`);
        }

        setDesktopViewport(width) {
            this.settings.desktopViewportWidth = width;
            this.settings.viewMode = 'desktop';
            this.saveSettings();
            this.applyViewMode();
            this.showNotification(`电脑视口设置为 ${width}px`);
        }

        setCustomMobileViewport() {
            const width = parseInt(prompt('请输入手机视口宽度 (px):', this.settings.customViewportWidth));
            if (!isNaN(width) && width >= 200 && width <= 2000) {
                this.setMobileViewport(width);
            } else if (!isNaN(width)) {
                this.showNotification('宽度无效 (200-2000)');
            }
            this.showMobileViewportMenu();
        }

        setCustomDesktopViewport() {
            const width = parseInt(prompt('请输入电脑视口宽度 (px):', this.settings.desktopViewportWidth));
            if (!isNaN(width) && width >= 800 && width <= 4000) {
                this.setDesktopViewport(width);
            } else if (!isNaN(width)) {
                this.showNotification('宽度无效 (800-4000)');
            }
            this.showDesktopViewportMenu();
        }

        showStatus() {
            const enabledHosts = GM_getValue('enabledHosts', {});
            alert(`当前模式: ${this.getCurrentStatusText()}\n已启用网站: ${Object.keys(enabledHosts).join(', ') || '无'}`);
        }

        applyViewMode() {
            if (!this.isEnabled) return;
            
            this.removeAllStyles();
            this.resetViewport();
            
            if (this.settings.viewMode === 'mobile') {
                this.applyMobileView();
            } else {
                this.applyDesktopView();
            }
        }

        applyMobileView() {
            this.setViewport(`width=${this.settings.customViewportWidth}, initial-scale=1.0, user-scalable=no`);
            
            const style = document.createElement('style');
            style.id = 'mobile-view-styles';
            style.textContent = `
                body {
                    width: ${this.settings.customViewportWidth}px !important;
                    max-width: ${this.settings.customViewportWidth}px !important;
                    min-width: ${this.settings.customViewportWidth}px !important;
                    margin: 0 auto !important;
                    transform-origin: top center !important;
                    overflow-x: hidden !important;
                }
                html {
                    overflow-x: hidden !important;
                }
                img, video {
                    max-width: 100% !important;
                    height: auto !important;
                }
                table {
                    width: 100% !important;
                }
            `;
            document.head.appendChild(style);
            
            this.forceLayoutUpdate();
        }

        applyDesktopView() {
            this.setViewport(`width=${this.settings.desktopViewportWidth}, initial-scale=1.0`);
            
            const style = document.createElement('style');
            style.id = 'desktop-view-styles';
            style.textContent = `
                body {
                    min-width: ${this.settings.desktopViewportWidth}px !important;
                    margin: 0 auto !important;
                }
                html {
                    overflow-x: auto !important;
                }
            `;
            document.head.appendChild(style);
            
            this.forceLayoutUpdate();
        }

        setViewport(content) {
            let viewport = document.querySelector('meta[name="viewport"]');
            if (!viewport) {
                viewport = document.createElement('meta');
                viewport.name = 'viewport';
                document.head.appendChild(viewport);
            }
            viewport.content = content;
        }

        resetViewport() {
            let viewport = document.querySelector('meta[name="viewport"]');
            if (viewport) {
                viewport.content = 'width=device-width, initial-scale=1.0';
            }
        }

        removeAllStyles() {
            ['mobile-view-styles', 'desktop-view-styles'].forEach(id => {
                const style = document.getElementById(id);
                if (style) style.remove();
            });
        }

        forceLayoutUpdate() {
            document.body.style.display = 'none';
            document.body.offsetHeight;
            document.body.style.display = '';
            window.dispatchEvent(new Event('resize'));
        }

        showNotification(message) {
            console.log(`🔧 视图转换: ${message}`);
            this.showTempMessage(message);
        }

        showTempMessage(message) {
            const div = document.createElement('div');
            div.textContent = `🔧 ${message}`;
            div.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                background: #4CAF50;
                color: white;
                padding: 10px 20px;
                border-radius: 5px;
                z-index: 10000;
                font-size: 14px;
                box-shadow: 0 2px 10px rgba(0,0,0,0.3);
            `;
            document.body.appendChild(div);
            setTimeout(() => div.remove(), 2000);
        }
    }

    new ViewConverter();
})();