全屏API

全屏API概述

全屏API(Fullscreen API)允许网页元素以全屏模式显示,隐藏浏览器界面元素,提供沉浸式的用户体验。这对于视频播放、游戏、图片展示等场景非常有用。

东巴文(db-w.cn) 认为:全屏API让Web应用能够提供原生应用般的沉浸式体验,是多媒体应用的重要工具。

全屏API特点

核心特点

特点 说明
沉浸式体验 隐藏浏览器界面,提供全屏显示
任意元素 任何DOM元素都可以全屏显示
事件监听 可以监听全屏状态变化
样式控制 可以自定义全屏时的样式
跨浏览器 需要处理浏览器前缀兼容性

API方法

// 全屏API方法
const FullscreenMethods = {
    // 进入全屏
    requestFullscreen: Element.prototype.requestFullscreen,
    webkitRequestFullscreen: Element.prototype.webkitRequestFullscreen,
    mozRequestFullScreen: Element.prototype.mozRequestFullScreen,
    msRequestFullscreen: Element.prototype.msRequestFullscreen,
    
    // 退出全屏
    exitFullscreen: Document.prototype.exitFullscreen,
    webkitExitFullscreen: Document.prototype.webkitExitFullscreen,
    mozCancelFullScreen: Document.prototype.mozCancelFullScreen,
    msExitFullscreen: Document.prototype.msExitFullscreen,
    
    // 全屏元素
    fullscreenElement: Document.prototype.fullscreenElement,
    webkitFullscreenElement: Document.prototype.webkitFullscreenElement,
    mozFullScreenElement: Document.prototype.mozFullScreenElement,
    msFullscreenElement: Document.prototype.msFullscreenElement
};

进入全屏

基本用法

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>进入全屏示例</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
        }
        
        .demo-container {
            width: 100%;
            height: 400px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 10px;
            margin: 20px 0;
            cursor: pointer;
            transition: transform 0.3s;
        }
        
        .demo-container:hover {
            transform: scale(1.02);
        }
        
        .demo-content {
            text-align: center;
            color: white;
        }
        
        .demo-content h2 {
            font-size: 36px;
            margin-bottom: 20px;
        }
        
        .demo-content p {
            font-size: 18px;
            opacity: 0.9;
        }
        
        .controls {
            display: flex;
            gap: 10px;
            justify-content: center;
            margin: 20px 0;
        }
        
        button {
            padding: 12px 24px;
            font-size: 16px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        
        button:hover {
            background: #0056b3;
        }
        
        button:disabled {
            background: #ccc;
            cursor: not-allowed;
        }
        
        .status {
            text-align: center;
            padding: 15px;
            background: #f9f9f9;
            border-radius: 5px;
            margin: 20px 0;
        }
        
        /* 全屏样式 */
        .demo-container:fullscreen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
        }
        
        .demo-container:-webkit-full-screen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
        }
        
        .demo-container:-moz-full-screen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
        }
        
        .demo-container:-ms-fullscreen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
        }
    </style>
</head>
<body>
    <h1>进入全屏示例</h1>
    
    <div class="demo-container" id="demoContainer" onclick="toggleFullscreen()">
        <div class="demo-content">
            <h2>点击进入全屏</h2>
            <p>按ESC键退出全屏</p>
        </div>
    </div>
    
    <div class="controls">
        <button onclick="enterFullscreen()">进入全屏</button>
        <button onclick="exitFullscreen()">退出全屏</button>
        <button onclick="toggleFullscreen()">切换全屏</button>
    </div>
    
    <div class="status">
        <strong>全屏状态:</strong><span id="fullscreenStatus">未全屏</span>
    </div>
    
    <script>
        // 获取元素
        const elem = document.getElementById('demoContainer');
        const statusElem = document.getElementById('fullscreenStatus');
        
        // 进入全屏
        function enterFullscreen() {
            if (elem.requestFullscreen) {
                elem.requestFullscreen();
            } else if (elem.webkitRequestFullscreen) {
                elem.webkitRequestFullscreen();
            } else if (elem.mozRequestFullScreen) {
                elem.mozRequestFullScreen();
            } else if (elem.msRequestFullscreen) {
                elem.msRequestFullscreen();
            }
        }
        
        // 退出全屏
        function exitFullscreen() {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        }
        
        // 切换全屏
        function toggleFullscreen() {
            if (!isFullscreen()) {
                enterFullscreen();
            } else {
                exitFullscreen();
            }
        }
        
        // 检查是否全屏
        function isFullscreen() {
            return !!(document.fullscreenElement || 
                     document.webkitFullscreenElement || 
                     document.mozFullScreenElement || 
                     document.msFullscreenElement);
        }
        
        // 更新状态
        function updateStatus() {
            statusElem.textContent = isFullscreen() ? '全屏中' : '未全屏';
        }
        
        // 监听全屏变化
        document.addEventListener('fullscreenchange', updateStatus);
        document.addEventListener('webkitfullscreenchange', updateStatus);
        document.addEventListener('mozfullscreenchange', updateStatus);
        document.addEventListener('MSFullscreenChange', updateStatus);
    </script>
</body>
</html>

全屏事件

事件监听

// 全屏事件类型
const FullscreenEvents = {
    change: 'fullscreenchange',          // 全屏状态变化
    error: 'fullscreenerror'             // 全屏错误
};

// 监听全屏变化
document.addEventListener('fullscreenchange', function(event) {
    if (document.fullscreenElement) {
        console.log('进入全屏模式');
        console.log('全屏元素:', document.fullscreenElement);
    } else {
        console.log('退出全屏模式');
    }
});

// 监听全屏错误
document.addEventListener('fullscreenerror', function(event) {
    console.error('全屏错误:', event);
});

// 兼容性处理
const fullscreenChangeEvents = [
    'fullscreenchange',
    'webkitfullscreenchange',
    'mozfullscreenchange',
    'MSFullscreenChange'
];

fullscreenChangeEvents.forEach(eventName => {
    document.addEventListener(eventName, handleFullscreenChange);
});

function handleFullscreenChange(event) {
    // 处理全屏变化
}

全屏样式

CSS伪类

/* 全屏时的样式 */
:fullscreen {
    background: black;
}

/* Webkit浏览器 */
:-webkit-full-screen {
    background: black;
}

/* Firefox浏览器 */
:-moz-full-screen {
    background: black;
}

/* IE/Edge浏览器 */
:-ms-fullscreen {
    background: black;
}

/* 全屏元素的子元素 */
:fullscreen .content {
    color: white;
}

/* 全屏时的背景 */
:fullscreen::backdrop {
    background: rgba(0, 0, 0, 0.5);
}

样式示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>全屏样式示例</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
        }
        
        .video-container {
            position: relative;
            width: 100%;
            background: #000;
            border-radius: 10px;
            overflow: hidden;
        }
        
        .video-placeholder {
            width: 100%;
            height: 450px;
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-size: 48px;
        }
        
        .video-controls {
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            padding: 20px;
            background: linear-gradient(transparent, rgba(0, 0, 0, 0.8));
            display: flex;
            align-items: center;
            gap: 15px;
            opacity: 0;
            transition: opacity 0.3s;
        }
        
        .video-container:hover .video-controls {
            opacity: 1;
        }
        
        .control-btn {
            width: 40px;
            height: 40px;
            background: rgba(255, 255, 255, 0.2);
            border: none;
            border-radius: 50%;
            color: white;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 18px;
            transition: background 0.3s;
        }
        
        .control-btn:hover {
            background: rgba(255, 255, 255, 0.3);
        }
        
        .progress-bar {
            flex: 1;
            height: 4px;
            background: rgba(255, 255, 255, 0.3);
            border-radius: 2px;
            cursor: pointer;
        }
        
        .progress-fill {
            width: 30%;
            height: 100%;
            background: #ff6b6b;
            border-radius: 2px;
        }
        
        .time-display {
            color: white;
            font-size: 14px;
        }
        
        /* 全屏样式 */
        .video-container:fullscreen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
        }
        
        .video-container:fullscreen .video-placeholder {
            height: 100vh;
        }
        
        .video-container:fullscreen .video-controls {
            opacity: 0;
        }
        
        .video-container:fullscreen:hover .video-controls {
            opacity: 1;
        }
        
        /* Webkit浏览器 */
        .video-container:-webkit-full-screen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
        }
        
        .video-container:-webkit-full-screen .video-placeholder {
            height: 100vh;
        }
        
        /* Firefox浏览器 */
        .video-container:-moz-full-screen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
        }
        
        .video-container:-moz-full-screen .video-placeholder {
            height: 100vh;
        }
        
        /* IE/Edge浏览器 */
        .video-container:-ms-fullscreen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
        }
        
        .video-container:-ms-fullscreen .video-placeholder {
            height: 100vh;
        }
    </style>
</head>
<body>
    <h1>全屏样式示例</h1>
    
    <div class="video-container" id="videoContainer">
        <div class="video-placeholder"></div>
        
        <div class="video-controls">
            <button class="control-btn" onclick="togglePlay()"></button>
            <button class="control-btn" onclick="toggleFullscreen()"></button>
            <div class="progress-bar">
                <div class="progress-fill"></div>
            </div>
            <div class="time-display">00:00 / 10:30</div>
        </div>
    </div>
    
    <script>
        const container = document.getElementById('videoContainer');
        
        function toggleFullscreen() {
            if (!isFullscreen()) {
                enterFullscreen();
            } else {
                exitFullscreen();
            }
        }
        
        function enterFullscreen() {
            if (container.requestFullscreen) {
                container.requestFullscreen();
            } else if (container.webkitRequestFullscreen) {
                container.webkitRequestFullscreen();
            } else if (container.mozRequestFullScreen) {
                container.mozRequestFullScreen();
            } else if (container.msRequestFullscreen) {
                container.msRequestFullscreen();
            }
        }
        
        function exitFullscreen() {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        }
        
        function isFullscreen() {
            return !!(document.fullscreenElement || 
                     document.webkitFullscreenElement || 
                     document.mozFullScreenElement || 
                     document.msFullscreenElement);
        }
        
        function togglePlay() {
            // 播放/暂停逻辑
            console.log('Toggle play');
        }
    </script>
</body>
</html>

全屏检测

检测全屏状态

// 检测全屏API支持
function isFullscreenSupported() {
    return !!(
        document.fullscreenEnabled ||
        document.webkitFullscreenEnabled ||
        document.mozFullScreenEnabled ||
        document.msFullscreenEnabled
    );
}

// 检测当前全屏状态
function isFullscreen() {
    return !!(
        document.fullscreenElement ||
        document.webkitFullscreenElement ||
        document.mozFullScreenElement ||
        document.msFullscreenElement
    );
}

// 获取全屏元素
function getFullscreenElement() {
    return (
        document.fullscreenElement ||
        document.webkitFullscreenElement ||
        document.mozFullScreenElement ||
        document.msFullscreenElement ||
        null
    );
}

// 使用示例
if (isFullscreenSupported()) {
    console.log('浏览器支持全屏API');
    
    if (isFullscreen()) {
        const elem = getFullscreenElement();
        console.log('当前全屏元素:', elem);
    }
} else {
    console.log('浏览器不支持全屏API');
}

综合示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>全屏画廊 - 东巴文</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f5f5f5;
            padding: 20px;
        }
        
        .header {
            text-align: center;
            margin-bottom: 30px;
        }
        
        .header h1 {
            font-size: 36px;
            color: #333;
            margin-bottom: 10px;
        }
        
        .header p {
            color: #666;
        }
        
        .controls {
            display: flex;
            justify-content: center;
            gap: 10px;
            margin-bottom: 20px;
        }
        
        button {
            padding: 10px 20px;
            font-size: 14px;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: background 0.3s;
        }
        
        button:hover {
            background: #0056b3;
        }
        
        button:disabled {
            background: #ccc;
            cursor: not-allowed;
        }
        
        .gallery {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 20px;
            max-width: 1200px;
            margin: 0 auto;
        }
        
        .gallery-item {
            position: relative;
            aspect-ratio: 16/9;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 10px;
            overflow: hidden;
            cursor: pointer;
            transition: transform 0.3s;
        }
        
        .gallery-item:hover {
            transform: scale(1.05);
        }
        
        .gallery-item::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.3);
            opacity: 0;
            transition: opacity 0.3s;
        }
        
        .gallery-item:hover::before {
            opacity: 1;
        }
        
        .gallery-item .icon {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 48px;
            color: white;
            z-index: 1;
        }
        
        .gallery-item .title {
            position: absolute;
            bottom: 20px;
            left: 20px;
            color: white;
            font-size: 18px;
            font-weight: bold;
            z-index: 1;
        }
        
        .gallery-item .fullscreen-btn {
            position: absolute;
            top: 20px;
            right: 20px;
            width: 40px;
            height: 40px;
            background: rgba(255, 255, 255, 0.2);
            border: none;
            border-radius: 50%;
            color: white;
            cursor: pointer;
            font-size: 18px;
            z-index: 1;
            opacity: 0;
            transition: opacity 0.3s;
        }
        
        .gallery-item:hover .fullscreen-btn {
            opacity: 1;
        }
        
        /* 全屏样式 */
        .gallery-item:fullscreen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        .gallery-item:fullscreen .icon {
            font-size: 120px;
        }
        
        .gallery-item:fullscreen .title {
            font-size: 36px;
            bottom: 50px;
        }
        
        .gallery-item:fullscreen .fullscreen-btn {
            opacity: 1;
            top: 30px;
            right: 30px;
            width: 60px;
            height: 60px;
            font-size: 24px;
        }
        
        /* Webkit浏览器 */
        .gallery-item:-webkit-full-screen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        /* Firefox浏览器 */
        .gallery-item:-moz-full-screen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        /* IE/Edge浏览器 */
        .gallery-item:-ms-fullscreen {
            width: 100vw;
            height: 100vh;
            border-radius: 0;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        .status-bar {
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            padding: 15px 30px;
            background: rgba(0, 0, 0, 0.8);
            color: white;
            border-radius: 10px;
            display: none;
            z-index: 1000;
        }
        
        .status-bar.show {
            display: block;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>🖼️ 全屏画廊</h1>
        <p>点击图片或全屏按钮进入全屏模式</p>
    </div>
    
    <div class="controls">
        <button onclick="enterFullscreenPage()">全屏页面</button>
        <button onclick="exitFullscreen()">退出全屏</button>
    </div>
    
    <div class="gallery">
        <div class="gallery-item" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);" onclick="toggleFullscreen(this)">
            <div class="icon">🏔️</div>
            <div class="title">山景</div>
            <button class="fullscreen-btn" onclick="event.stopPropagation(); toggleFullscreen(this.parentElement)"></button>
        </div>
        
        <div class="gallery-item" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);" onclick="toggleFullscreen(this)">
            <div class="icon">🌸</div>
            <div class="title">花海</div>
            <button class="fullscreen-btn" onclick="event.stopPropagation(); toggleFullscreen(this.parentElement)"></button>
        </div>
        
        <div class="gallery-item" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);" onclick="toggleFullscreen(this)">
            <div class="icon">🌊</div>
            <div class="title">海洋</div>
            <button class="fullscreen-btn" onclick="event.stopPropagation(); toggleFullscreen(this.parentElement)"></button>
        </div>
        
        <div class="gallery-item" style="background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);" onclick="toggleFullscreen(this)">
            <div class="icon">🌲</div>
            <div class="title">森林</div>
            <button class="fullscreen-btn" onclick="event.stopPropagation(); toggleFullscreen(this.parentElement)"></button>
        </div>
        
        <div class="gallery-item" style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);" onclick="toggleFullscreen(this)">
            <div class="icon">🌅</div>
            <div class="title">日落</div>
            <button class="fullscreen-btn" onclick="event.stopPropagation(); toggleFullscreen(this.parentElement)"></button>
        </div>
        
        <div class="gallery-item" style="background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);" onclick="toggleFullscreen(this)">
            <div class="icon">☁️</div>
            <div class="title">天空</div>
            <button class="fullscreen-btn" onclick="event.stopPropagation(); toggleFullscreen(this.parentElement)"></button>
        </div>
    </div>
    
    <div class="status-bar" id="statusBar">
        按 ESC 键退出全屏
    </div>
    
    <script>
        // 全屏工具类
        class FullscreenManager {
            constructor() {
                this.init();
            }
            
            init() {
                // 监听全屏变化
                this.addFullscreenListener(this.handleFullscreenChange.bind(this));
                
                // 检测支持
                if (!this.isSupported()) {
                    console.warn('浏览器不支持全屏API');
                }
            }
            
            isSupported() {
                return !!(
                    document.fullscreenEnabled ||
                    document.webkitFullscreenEnabled ||
                    document.mozFullScreenEnabled ||
                    document.msFullscreenEnabled
                );
            }
            
            enter(element) {
                if (element.requestFullscreen) {
                    return element.requestFullscreen();
                } else if (element.webkitRequestFullscreen) {
                    return element.webkitRequestFullscreen();
                } else if (element.mozRequestFullScreen) {
                    return element.mozRequestFullScreen();
                } else if (element.msRequestFullscreen) {
                    return element.msRequestFullscreen();
                }
                
                return Promise.reject(new Error('全屏API不支持'));
            }
            
            exit() {
                if (document.exitFullscreen) {
                    return document.exitFullscreen();
                } else if (document.webkitExitFullscreen) {
                    return document.webkitExitFullscreen();
                } else if (document.mozCancelFullScreen) {
                    return document.mozCancelFullScreen();
                } else if (document.msExitFullscreen) {
                    return document.msExitFullscreen();
                }
                
                return Promise.reject(new Error('全屏API不支持'));
            }
            
            toggle(element) {
                if (this.isFullscreen()) {
                    return this.exit();
                } else {
                    return this.enter(element);
                }
            }
            
            isFullscreen() {
                return !!(
                    document.fullscreenElement ||
                    document.webkitFullscreenElement ||
                    document.mozFullScreenElement ||
                    document.msFullscreenElement
                );
            }
            
            getElement() {
                return (
                    document.fullscreenElement ||
                    document.webkitFullscreenElement ||
                    document.mozFullScreenElement ||
                    document.msFullscreenElement ||
                    null
                );
            }
            
            addFullscreenListener(callback) {
                const events = [
                    'fullscreenchange',
                    'webkitfullscreenchange',
                    'mozfullscreenchange',
                    'MSFullscreenChange'
                ];
                
                events.forEach(event => {
                    document.addEventListener(event, callback);
                });
            }
            
            handleFullscreenChange() {
                const statusBar = document.getElementById('statusBar');
                
                if (this.isFullscreen()) {
                    statusBar.classList.add('show');
                    setTimeout(() => {
                        statusBar.classList.remove('show');
                    }, 3000);
                } else {
                    statusBar.classList.remove('show');
                }
            }
        }
        
        // 初始化全屏管理器
        const fullscreenManager = new FullscreenManager();
        
        // 切换全屏
        function toggleFullscreen(element) {
            fullscreenManager.toggle(element);
        }
        
        // 全屏页面
        function enterFullscreenPage() {
            fullscreenManager.enter(document.documentElement);
        }
        
        // 退出全屏
        function exitFullscreen() {
            fullscreenManager.exit();
        }
    </script>
</body>
</html>

最佳实践

1. 兼容性处理

// 推荐:封装兼容性方法
class FullscreenHelper {
    static request(element) {
        if (element.requestFullscreen) {
            return element.requestFullscreen();
        } else if (element.webkitRequestFullscreen) {
            return element.webkitRequestFullscreen();
        } else if (element.mozRequestFullScreen) {
            return element.mozRequestFullScreen();
        } else if (element.msRequestFullscreen) {
            return element.msRequestFullscreen();
        }
        return Promise.reject(new Error('不支持全屏'));
    }
    
    static exit() {
        if (document.exitFullscreen) {
            return document.exitFullscreen();
        } else if (document.webkitExitFullscreen) {
            return document.webkitExitFullscreen();
        } else if (document.mozCancelFullScreen) {
            return document.mozCancelFullScreen();
        } else if (document.msExitFullscreen) {
            return document.msExitFullscreen();
        }
        return Promise.reject(new Error('不支持全屏'));
    }
    
    static isFullscreen() {
        return !!(
            document.fullscreenElement ||
            document.webkitFullscreenElement ||
            document.mozFullScreenElement ||
            document.msFullscreenElement
        );
    }
}

// 使用
FullscreenHelper.request(element)
    .then(() => console.log('进入全屏'))
    .catch(err => console.error('全屏失败:', err));

2. 用户交互触发

// 推荐:在用户交互时触发全屏
document.getElementById('fullscreenBtn').addEventListener('click', function() {
    element.requestFullscreen().catch(err => {
        console.error('全屏失败:', err);
    });
});

// 不推荐:自动触发全屏
window.addEventListener('load', function() {
    element.requestFullscreen(); // 可能被浏览器阻止
});

3. 提供退出方式

// 推荐:提供明确的退出方式
function enterFullscreen(element) {
    element.requestFullscreen();
    
    // 显示提示
    showNotification('按 ESC 键退出全屏');
    
    // 添加退出按钮
    const exitBtn = document.createElement('button');
    exitBtn.textContent = '退出全屏';
    exitBtn.className = 'exit-fullscreen-btn';
    exitBtn.onclick = () => document.exitFullscreen();
    element.appendChild(exitBtn);
}

// 监听全屏变化,移除退出按钮
document.addEventListener('fullscreenchange', function() {
    if (!document.fullscreenElement) {
        const exitBtn = document.querySelector('.exit-fullscreen-btn');
        if (exitBtn) {
            exitBtn.remove();
        }
    }
});

东巴文点评:全屏API使用要注重用户体验,提供明确的进入和退出方式。

学习检验

知识点测试

问题1:以下哪个方法用于让元素进入全屏模式?

A. document.enterFullscreen() B. element.requestFullscreen() C. element.fullscreen() D. document.requestFullscreen()

<details> <summary>点击查看答案</summary>

答案:B

东巴文解释:使用element.requestFullscreen()方法让指定元素进入全屏模式。注意是元素的方法,不是document的方法。document.exitFullscreen()用于退出全屏。

</details>

问题2:以下哪个CSS伪类用于设置全屏时的样式?

A. :fullscreen-mode B. :full-screen C. :fullscreen D. :in-fullscreen

<details> <summary>点击查看答案</summary>

答案:C

东巴文解释:使用:fullscreen伪类设置元素全屏时的样式。需要注意浏览器兼容性,可能需要添加-webkit--moz-等前缀。

</details>

实践任务

任务:创建一个图片查看器,支持全屏查看图片,并提供缩放、旋转等功能。

<details> <summary>点击查看参考答案</summary>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片查看器 - 东巴文</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f5f5f5;
            padding: 20px;
        }
        
        .header {
            text-align: center;
            margin-bottom: 30px;
        }
        
        .header h1 {
            font-size: 36px;
            color: #333;
            margin-bottom: 10px;
        }
        
        .image-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            max-width: 1200px;
            margin: 0 auto;
        }
        
        .image-item {
            aspect-ratio: 1;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 10px;
            cursor: pointer;
            transition: transform 0.3s;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 48px;
        }
        
        .image-item:hover {
            transform: scale(1.05);
        }
        
        .viewer {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            background: rgba(0, 0, 0, 0.95);
            display: none;
            align-items: center;
            justify-content: center;
            z-index: 1000;
        }
        
        .viewer.active {
            display: flex;
        }
        
        .viewer:fullscreen {
            background: rgba(0, 0, 0, 0.98);
        }
        
        .viewer-content {
            position: relative;
            max-width: 90vw;
            max-height: 90vh;
        }
        
        .viewer-image {
            width: 100%;
            height: 100%;
            object-fit: contain;
            transition: transform 0.3s;
        }
        
        .viewer-controls {
            position: absolute;
            bottom: 30px;
            left: 50%;
            transform: translateX(-50%);
            display: flex;
            gap: 10px;
            background: rgba(255, 255, 255, 0.1);
            padding: 15px;
            border-radius: 10px;
        }
        
        .control-btn {
            width: 50px;
            height: 50px;
            background: rgba(255, 255, 255, 0.2);
            border: none;
            border-radius: 50%;
            color: white;
            cursor: pointer;
            font-size: 20px;
            transition: background 0.3s;
        }
        
        .control-btn:hover {
            background: rgba(255, 255, 255, 0.3);
        }
        
        .close-btn {
            position: absolute;
            top: 30px;
            right: 30px;
            width: 60px;
            height: 60px;
            background: rgba(255, 255, 255, 0.1);
            border: none;
            border-radius: 50%;
            color: white;
            cursor: pointer;
            font-size: 24px;
        }
        
        .close-btn:hover {
            background: rgba(255, 255, 255, 0.2);
        }
        
        .info {
            position: absolute;
            top: 30px;
            left: 30px;
            color: white;
            font-size: 14px;
            background: rgba(0, 0, 0, 0.5);
            padding: 10px 15px;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <div class="header">
        <h1>🖼️ 图片查看器</h1>
        <p>点击图片查看大图,支持全屏、缩放、旋转</p>
    </div>
    
    <div class="image-grid">
        <div class="image-item" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);" onclick="openViewer(0)">🏔️</div>
        <div class="image-item" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);" onclick="openViewer(1)">🌸</div>
        <div class="image-item" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);" onclick="openViewer(2)">🌊</div>
        <div class="image-item" style="background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);" onclick="openViewer(3)">🌲</div>
        <div class="image-item" style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);" onclick="openViewer(4)">🌅</div>
        <div class="image-item" style="background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);" onclick="openViewer(5)">☁️</div>
    </div>
    
    <div class="viewer" id="viewer">
        <button class="close-btn" onclick="closeViewer()"></button>
        
        <div class="info" id="viewerInfo">图片 1/6</div>
        
        <div class="viewer-content">
            <div class="viewer-image" id="viewerImage" style="font-size: 200px; text-align: center;">🏔️</div>
        </div>
        
        <div class="viewer-controls">
            <button class="control-btn" onclick="previousImage()"></button>
            <button class="control-btn" onclick="zoomOut()"></button>
            <button class="control-btn" onclick="resetView()"></button>
            <button class="control-btn" onclick="zoomIn()">+</button>
            <button class="control-btn" onclick="rotateLeft()"></button>
            <button class="control-btn" onclick="rotateRight()"></button>
            <button class="control-btn" onclick="toggleFullscreen()"></button>
            <button class="control-btn" onclick="nextImage()"></button>
        </div>
    </div>
    
    <script>
        // 图片数据
        const images = [
            { emoji: '🏔️', title: '山景', background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' },
            { emoji: '🌸', title: '花海', background: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)' },
            { emoji: '🌊', title: '海洋', background: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)' },
            { emoji: '🌲', title: '森林', background: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)' },
            { emoji: '🌅', title: '日落', background: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)' },
            { emoji: '☁️', title: '天空', background: 'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)' }
        ];
        
        // 查看器状态
        let currentIndex = 0;
        let scale = 1;
        let rotation = 0;
        
        // 打开查看器
        function openViewer(index) {
            currentIndex = index;
            scale = 1;
            rotation = 0;
            
            updateViewer();
            
            document.getElementById('viewer').classList.add('active');
            document.getElementById('viewer').style.background = images[index].background;
        }
        
        // 关闭查看器
        function closeViewer() {
            document.getElementById('viewer').classList.remove('active');
            
            // 如果在全屏模式,退出全屏
            if (isFullscreen()) {
                exitFullscreen();
            }
        }
        
        // 更新查看器
        function updateViewer() {
            const image = images[currentIndex];
            const imageElement = document.getElementById('viewerImage');
            
            imageElement.textContent = image.emoji;
            imageElement.style.transform = `scale(${scale}) rotate(${rotation}deg)`;
            
            document.getElementById('viewerInfo').textContent = 
                `${image.title} - 图片 ${currentIndex + 1}/${images.length}`;
        }
        
        // 上一张
        function previousImage() {
            currentIndex = (currentIndex - 1 + images.length) % images.length;
            scale = 1;
            rotation = 0;
            updateViewer();
        }
        
        // 下一张
        function nextImage() {
            currentIndex = (currentIndex + 1) % images.length;
            scale = 1;
            rotation = 0;
            updateViewer();
        }
        
        // 放大
        function zoomIn() {
            scale = Math.min(scale + 0.2, 3);
            updateViewer();
        }
        
        // 缩小
        function zoomOut() {
            scale = Math.max(scale - 0.2, 0.5);
            updateViewer();
        }
        
        // 重置
        function resetView() {
            scale = 1;
            rotation = 0;
            updateViewer();
        }
        
        // 左旋转
        function rotateLeft() {
            rotation -= 90;
            updateViewer();
        }
        
        // 右旋转
        function rotateRight() {
            rotation += 90;
            updateViewer();
        }
        
        // 切换全屏
        function toggleFullscreen() {
            const viewer = document.getElementById('viewer');
            
            if (!isFullscreen()) {
                enterFullscreen(viewer);
            } else {
                exitFullscreen();
            }
        }
        
        // 进入全屏
        function enterFullscreen(element) {
            if (element.requestFullscreen) {
                element.requestFullscreen();
            } else if (element.webkitRequestFullscreen) {
                element.webkitRequestFullscreen();
            } else if (element.mozRequestFullScreen) {
                element.mozRequestFullScreen();
            } else if (element.msRequestFullscreen) {
                element.msRequestFullscreen();
            }
        }
        
        // 退出全屏
        function exitFullscreen() {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        }
        
        // 检查全屏
        function isFullscreen() {
            return !!(
                document.fullscreenElement ||
                document.webkitFullscreenElement ||
                document.mozFullScreenElement ||
                document.msFullscreenElement
            );
        }
        
        // 键盘控制
        document.addEventListener('keydown', function(e) {
            if (!document.getElementById('viewer').classList.contains('active')) {
                return;
            }
            
            switch (e.key) {
                case 'Escape':
                    closeViewer();
                    break;
                case 'ArrowLeft':
                    previousImage();
                    break;
                case 'ArrowRight':
                    nextImage();
                    break;
                case '+':
                case '=':
                    zoomIn();
                    break;
                case '-':
                    zoomOut();
                    break;
                case 'r':
                    rotateRight();
                    break;
                case 'f':
                    toggleFullscreen();
                    break;
            }
        });
        
        // 鼠标滚轮缩放
        document.getElementById('viewer').addEventListener('wheel', function(e) {
            e.preventDefault();
            
            if (e.deltaY < 0) {
                zoomIn();
            } else {
                zoomOut();
            }
        });
    </script>
</body>
</html>
</details>

东巴文(db-w.cn) - 让编程学习更有趣、更高效!