Greasy Fork

Greasy Fork is available in English.

双击全屏(使用手机浏览器)

安卓手机浏览器双击切换全屏,避免输入区域触发,不影响视频操作,键盘弹出时对话框自动抬高

当前为 2025-12-04 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         双击全屏(使用手机浏览器)
// @namespace    http://tampermonkey.net/
// @version      1.4
// @description  安卓手机浏览器双击切换全屏,避免输入区域触发,不影响视频操作,键盘弹出时对话框自动抬高
// @author       青野
// @match        *://*/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    let lastTapTime = 0;
    const doubleTapDelay = 300; // 双击间隔时间(毫秒)

    // 检查是否为可输入元素
    function isInputElement(element) {
        const tagName = element.tagName.toLowerCase();
        const inputTags = ['input', 'textarea', 'select'];
        const isContentEditable = element.isContentEditable;
        const isInputRole = element.getAttribute('role') === 'textbox';
        
        return inputTags.includes(tagName) || isContentEditable || isInputRole;
    }

    // 检查是否在视频控件区域
    function isVideoControls(element) {
        let current = element;
        while (current) {
            if (current.tagName && current.tagName.toLowerCase() === 'video') {
                return false; // 视频元素本身可以双击
            }
            // 检查是否是视频控件容器
            const className = current.className || '';
            if (typeof className === 'string' && 
                (className.includes('controls') || 
                 className.includes('player-controls') ||
                 className.includes('video-controls'))) {
                return true;
            }
            current = current.parentElement;
        }
        return false;
    }

    // 切换全屏
    function toggleFullscreen() {
        if (!document.fullscreenElement && 
            !document.webkitFullscreenElement && 
            !document.mozFullScreenElement && 
            !document.msFullscreenElement) {
            // 进入全屏
            const elem = document.documentElement;
            if (elem.requestFullscreen) {
                elem.requestFullscreen();
            } else if (elem.webkitRequestFullscreen) {
                elem.webkitRequestFullscreen();
            } else if (elem.mozRequestFullScreen) {
                elem.mozRequestFullScreen();
            } else if (elem.msRequestFullscreen) {
                elem.msRequestFullscreen();
            }
        } else {
            // 退出全屏
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        }
    }

    // 双击事件处理
    function handleTap(e) {
        const target = e.target;
        
        // 忽略输入元素
        if (isInputElement(target)) {
            return;
        }
        
        // 忽略视频控件区域
        if (isVideoControls(target)) {
            return;
        }

        const currentTime = new Date().getTime();
        const tapLength = currentTime - lastTapTime;
        
        if (tapLength < doubleTapDelay && tapLength > 0) {
            // 双击检测成功
            e.preventDefault();
            toggleFullscreen();
            lastTapTime = 0; // 重置
        } else {
            lastTapTime = currentTime;
        }
    }

    // 监听触摸结束事件(移动端)
    document.addEventListener('touchend', function(e) {
        // 确保只是单点触摸
        if (e.changedTouches.length === 1) {
            handleTap(e);
        }
    }, { passive: false });

    // 键盘弹出时对话框抬高处理
    function handleKeyboardResize() {
        // 检测可能的对话框元素
        const dialogSelectors = [
            'dialog',
            '[role="dialog"]',
            '[role="alertdialog"]',
            '.modal',
            '.dialog',
            '.popup',
            '[class*="modal"]',
            '[class*="dialog"]',
            '[class*="popup"]'
        ];

        const visualViewport = window.visualViewport;
        
        if (visualViewport) {
            visualViewport.addEventListener('resize', function() {
                const keyboardHeight = window.innerHeight - visualViewport.height;
                
                dialogSelectors.forEach(selector => {
                    const dialogs = document.querySelectorAll(selector);
                    dialogs.forEach(dialog => {
                        if (dialog.offsetParent !== null) { // 可见的对话框
                            if (keyboardHeight > 100) { // 键盘可能已弹出
                                dialog.style.transition = 'transform 0.3s ease';
                                dialog.style.transform = `translateY(-${keyboardHeight}px)`;
                            } else {
                                dialog.style.transform = 'translateY(0)';
                            }
                        }
                    });
                });
            });

            visualViewport.addEventListener('scroll', function() {
                // 保持对话框位置
                const scrollTop = visualViewport.offsetTop;
                dialogSelectors.forEach(selector => {
                    const dialogs = document.querySelectorAll(selector);
                    dialogs.forEach(dialog => {
                        if (dialog.offsetParent !== null && 
                            dialog.style.position === 'fixed') {
                            dialog.style.top = `${scrollTop}px`;
                        }
                    });
                });
            });
        }

        // 备用方案:监听焦点事件
        document.addEventListener('focusin', function(e) {
            if (isInputElement(e.target)) {
                setTimeout(() => {
                    dialogSelectors.forEach(selector => {
                        const dialogs = document.querySelectorAll(selector);
                        dialogs.forEach(dialog => {
                            if (dialog.offsetParent !== null) {
                                dialog.scrollIntoView({ behavior: 'smooth', block: 'center' });
                            }
                        });
                    });
                }, 300);
            }
        });

        document.addEventListener('focusout', function(e) {
            if (isInputElement(e.target)) {
                setTimeout(() => {
                    dialogSelectors.forEach(selector => {
                        const dialogs = document.querySelectorAll(selector);
                        dialogs.forEach(dialog => {
                            dialog.style.transform = 'translateY(0)';
                        });
                    });
                }, 100);
            }
        });
    }

    // 初始化键盘处理
    handleKeyboardResize();

    console.log('🐵 双击全屏脚本已加载 - 作者:青野');
})();