全屏API(Fullscreen API)允许网页元素以全屏模式显示,隐藏浏览器界面元素,提供沉浸式的用户体验。这对于视频播放、游戏、图片展示等场景非常有用。
东巴文(db-w.cn) 认为:全屏API让Web应用能够提供原生应用般的沉浸式体验,是多媒体应用的重要工具。
| 特点 | 说明 |
|---|---|
| 沉浸式体验 | 隐藏浏览器界面,提供全屏显示 |
| 任意元素 | 任何DOM元素都可以全屏显示 |
| 事件监听 | 可以监听全屏状态变化 |
| 样式控制 | 可以自定义全屏时的样式 |
| 跨浏览器 | 需要处理浏览器前缀兼容性 |
// 全屏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) {
// 处理全屏变化
}
/* 全屏时的样式 */
: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>
// 推荐:封装兼容性方法
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));
// 推荐:在用户交互时触发全屏
document.getElementById('fullscreenBtn').addEventListener('click', function() {
element.requestFullscreen().catch(err => {
console.error('全屏失败:', err);
});
});
// 不推荐:自动触发全屏
window.addEventListener('load', function() {
element.requestFullscreen(); // 可能被浏览器阻止
});
// 推荐:提供明确的退出方式
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()用于退出全屏。
问题2:以下哪个CSS伪类用于设置全屏时的样式?
A. :fullscreen-mode B. :full-screen C. :fullscreen D. :in-fullscreen
<details> <summary>点击查看答案</summary>答案:C
东巴文解释:使用:fullscreen伪类设置元素全屏时的样式。需要注意浏览器兼容性,可能需要添加-webkit-、-moz-等前缀。
任务:创建一个图片查看器,支持全屏查看图片,并提供缩放、旋转等功能。
<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) - 让编程学习更有趣、更高效!