在当今数字化时代,传统文化与现代技术的融合为文学欣赏带来了全新的体验。本文将以唐代诗人李绅的《悯农》为例,详细介绍如何创建一个结合视频背景和背景音乐的古诗欣赏网页。我们将从基础结构开始,逐步解决实际开发中遇到的浏览器兼容性问题,最终打造一个既美观又功能完善的页面。
我们的目标是创建一个沉浸式的古诗欣赏体验,通过视觉和听觉元素增强诗歌的感染力。具体要实现:
"形式服务于内容"是我们的核心设计理念。所有技术元素都旨在强化诗歌的主题——农民劳作的艰辛和粮食的来之不易。视频选择田野劳作场景,音乐采用舒缓的古典风格,颜色搭配上使用金色文字象征稻谷,深色背景象征土地。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>悯农古诗欣赏</title>
<link href="https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng&display=swap" rel="stylesheet">
<style>
/* 样式将在下一部分详细介绍 */
</style>
</head>
<body>
<!-- 视频背景 -->
<video autoplay muted loop id="video-background">
<source src="assets/farmland.mp4" type="video/mp4">
<!-- 备用内容 -->
</video>
<!-- 古诗内容容器 -->
<div class="poem-container">
<h1>悯农</h1>
<div class="poem">
<p>锄禾日当午,汗滴禾下土。</p>
<p>谁知盘中餐,粒粒皆辛苦。</p>
</div>
<div class="author">—— 李绅</div>
</div>
<!-- 背景音乐 -->
<audio id="bg-music" loop>
<source src="assets/chinese-garden.mp3" type="audio/mpeg">
</audio>
<script>
// JavaScript交互代码
</script>
</body>
</html><video>标签实现全屏背景,添加autoplay、muted、loop属性确保自动循环播放<audio>标签,设置为循环播放body {
margin: 0;
padding: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-family: "楷体", "STKaiti", "Ma Shan Zheng", serif;
overflow: hidden;
color: #fff;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
#video-background {
position: fixed;
right: 0;
bottom: 0;
min-width: 100%;
min-height: 100%;
z-index: -1;
object-fit: cover;
}.poem-container {
background-color: rgba(0, 0, 0, 0.6);
padding: 40px;
border-radius: 10px;
max-width: 600px;
text-align: center;
backdrop-filter: blur(5px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
transform: translateY(-20px);
animation: fadeIn 1.5s ease-out forwards;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
h1 {
font-size: 2.5em;
margin-bottom: 30px;
color: #f8e58c;
letter-spacing: 5px;
}
.poem {
font-size: 1.8em;
line-height: 2.5em;
letter-spacing: 2px;
}
.author {
font-size: 1.5em;
margin-top: 30px;
font-style: italic;
color: #ccc;
}.controls {
margin-top: 30px;
display: flex;
justify-content: center;
gap: 15px;
}
button {
background: rgba(255, 255, 255, 0.2);
border: none;
color: white;
padding: 12px 24px;
border-radius: 50px;
cursor: pointer;
font-family: inherit;
font-size: 1em;
transition: all 0.3s;
min-width: 120px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
button:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
}
button:active {
transform: translateY(1px);
}// 获取DOM元素
const bgMusic = document.getElementById('bg-music');
const musicBtn = document.getElementById('music-btn');
const muteBtn = document.getElementById('mute-btn');
const videoBg = document.getElementById('video-background');
// 初始化状态
let isMusicPlaying = false;
let isMuted = true;
// 音乐播放控制
musicBtn.addEventListener('click', function() {
if (isMusicPlaying) {
bgMusic.pause();
musicBtn.textContent = '播放音乐';
} else {
// 尝试播放音乐
const playPromise = bgMusic.play();
if (playPromise !== undefined) {
playPromise.then(_ => {
isMusicPlaying = true;
musicBtn.textContent = '暂停音乐';
})
.catch(error => {
console.log('播放失败:', error);
alert('请先取消静音后再播放音乐');
});
}
}
isMusicPlaying = !isMusicPlaying;
});
// 静音控制
muteBtn.addEventListener('click', function() {
isMuted = !isMuted;
bgMusic.muted = isMuted;
videoBg.muted = isMuted;
muteBtn.textContent = isMuted ? '取消静音' : '静音';
});现代浏览器为防止滥用,限制了自动播放功能。我们的解决方案:
// 初始化设置
function initMedia() {
// 视频默认静音自动播放
videoBg.muted = true;
videoBg.play().catch(e => {
console.log('视频自动播放被阻止:', e);
showFallbackImage();
});
// 音乐默认静音
bgMusic.muted = true;
// 用户首次交互后尝试取消静音
document.addEventListener('click', function firstInteraction() {
// 尝试取消视频静音
videoBg.muted = false;
// 移除事件监听
document.removeEventListener('click', firstInteraction);
}, { once: true });
}
// 显示备用图片
function showFallbackImage() {
const fallback = document.createElement('img');
fallback.src = 'assets/fallback-image.jpg';
fallback.className = 'fallback-image';
fallback.alt = '田园风光';
document.body.appendChild(fallback);
}
// 页面加载完成后初始化
window.addEventListener('DOMContentLoaded', initMedia);// 添加加载状态指示
const loadingIndicator = document.createElement('div');
loadingIndicator.className = 'loading-indicator';
document.body.appendChild(loadingIndicator);
// 检查所有媒体加载状态
Promise.all([
new Promise(resolve => {
videoBg.addEventListener('loadeddata', resolve);
videoBg.addEventListener('error', resolve);
}),
new Promise(resolve => {
bgMusic.addEventListener('canplaythrough', resolve);
bgMusic.addEventListener('error', resolve);
})
]).then(() => {
// 所有媒体加载完成后移除加载指示
loadingIndicator.style.opacity = '0';
setTimeout(() => {
loadingIndicator.remove();
}, 500);
});
// 添加键盘快捷键
document.addEventListener('keydown', (e) => {
if (e.code === 'Space') {
e.preventDefault();
musicBtn.click();
} else if (e.code === 'KeyM') {
muteBtn.click();
}
});muted属性)playsinline属性以兼容iOS// 延迟加载非关键资源
window.addEventListener('load', function() {
// 预加载可能用到的其他资源
const preloads = [
{ href: 'assets/fallback-image.jpg', as: 'image' },
{ href: 'assets/audio-waveform.png', as: 'image' }
];
preloads.forEach(item => {
const link = document.createElement('link');
link.rel = 'preload';
link.href = item.href;
link.as = item.as;
document.head.appendChild(link);
});
});
// 视频自适应质量
function adjustVideoQuality() {
const connection = navigator.connection;
if (connection) {
const effectiveType = connection.effectiveType;
if (effectiveType === 'slow-2g' || effectiveType === '2g') {
videoBg.src = 'assets/farmland-low.mp4';
}
}
}/* 平板设备样式调整 */
@media (max-width: 768px) {
.poem-container {
padding: 30px;
max-width: 85%;
}
h1 {
font-size: 2em;
}
.poem {
font-size: 1.5em;
line-height: 2em;
}
}
/* 手机设备样式调整 */
@media (max-width: 480px) {
.poem-container {
padding: 20px;
max-width: 90%;
}
h1 {
font-size: 1.8em;
margin-bottom: 20px;
}
.poem {
font-size: 1.3em;
line-height: 1.8em;
}
.controls {
flex-direction: column;
gap: 10px;
}
button {
width: 100%;
}
}以下是整合所有优化的完整代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>悯农古诗欣赏</title>
<link href="https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng&display=swap" rel="stylesheet">
<style>
body {
margin: 0;
padding: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-family: "楷体", "STKaiti", "Ma Shan Zheng", serif;
overflow: hidden;
color: #fff;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
background-color: #222;
}
#video-background {
position: fixed;
right: 0;
bottom: 0;
min-width: 100%;
min-height: 100%;
z-index: -1;
object-fit: cover;
transition: opacity 1s;
}
.fallback-image {
position: fixed;
width: 100%;
height: 100%;
object-fit: cover;
z-index: -2;
display: none;
}
.poem-container {
background-color: rgba(0, 0, 0, 0.6);
padding: 40px;
border-radius: 10px;
max-width: 600px;
text-align: center;
backdrop-filter: blur(5px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
transform: translateY(-20px);
animation: fadeIn 1.5s ease-out forwards;
margin: 20px;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
h1 {
font-size: 2.5em;
margin-bottom: 30px;
color: #f8e58c;
letter-spacing: 5px;
}
.poem {
font-size: 1.8em;
line-height: 2.5em;
letter-spacing: 2px;
}
.author {
font-size: 1.5em;
margin-top: 30px;
font-style: italic;
color: #ccc;
}
.controls {
margin-top: 30px;
display: flex;
justify-content: center;
gap: 15px;
}
button {
background: rgba(255, 255, 255, 0.2);
border: none;
color: white;
padding: 12px 24px;
border-radius: 50px;
cursor: pointer;
font-family: inherit;
font-size: 1em;
transition: all 0.3s;
min-width: 120px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
button:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
}
button:active {
transform: translateY(1px);
}
.loading-indicator {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 100;
transition: opacity 0.5s;
}
.loading-indicator::after {
content: "加载中...";
color: white;
font-size: 1.5em;
}
@media (max-width: 768px) {
.poem-container {
padding: 30px;
max-width: 85%;
}
h1 {
font-size: 2em;
}
.poem {
font-size: 1.5em;
line-height: 2em;
}
}
@media (max-width: 480px) {
.poem-container {
padding: 20px;
max-width: 90%;
}
h1 {
font-size: 1.8em;
margin-bottom: 20px;
}
.poem {
font-size: 1.3em;
line-height: 1.8em;
}
.controls {
flex-direction: column;
gap: 10px;
}
button {
width: 100%;
}
}
</style>
</head>
<body>
<!-- 视频背景 -->
<video autoplay muted loop playsinline id="video-background">
<source src="assets/farmland.mp4" type="video/mp4">
<img src="assets/fallback-image.jpg" class="fallback-image" alt="田园风光">
</video>
<!-- 古诗内容容器 -->
<div class="poem-container">
<h1>悯农</h1>
<div class="poem">
<p>锄禾日当午,汗滴禾下土。</p>
<p>谁知盘中餐,粒粒皆辛苦。</p>
</div>
<div class="author">—— 李绅</div>
<!-- 控制按钮 -->
<div class="controls">
<button id="music-btn">播放音乐</button>
<button id="mute-btn">取消静音</button>
</div>
</div>
<!-- 背景音乐 -->
<audio id="bg-music" loop>
<source src="assets/chinese-garden.mp3" type="audio/mpeg">
</audio>
<!-- 加载指示器 -->
<div class="loading-indicator"></div>
<script>
// 获取DOM元素
const bgMusic = document.getElementById('bg-music');
const musicBtn = document.getElementById('music-btn');
const muteBtn = document.getElementById('mute-btn');
const videoBg = document.getElementById('video-background');
const loadingIndicator = document.querySelector('.loading-indicator');
// 初始化状态
let isMusicPlaying = false;
let isMuted = true;
// 初始化媒体
function initMedia() {
// 视频默认静音自动播放
videoBg.muted = true;
const videoPromise = videoBg.play().catch(e => {
console.log('视频自动播放被阻止:', e);
showFallbackImage();
});
// 音乐默认静音
bgMusic.muted = true;
// 用户首次交互后尝试取消静音
document.addEventListener('click', function firstInteraction() {
// 尝试取消视频静音
videoBg.muted = false;
// 移除事件监听
document.removeEventListener('click', firstInteraction);
}, { once: true });
return Promise.all([videoPromise]);
}
// 显示备用图片
function showFallbackImage() {
const fallback = document.querySelector('.fallback-image');
if (fallback) {
fallback.style.display = 'block';
videoBg.style.display = 'none';
}
}
// 音乐播放控制
musicBtn.addEventListener('click', function() {
if (isMusicPlaying) {
bgMusic.pause();
musicBtn.textContent = '播放音乐';
} else {
// 尝试播放音乐
const playPromise = bgMusic.play();
if (playPromise !== undefined) {
playPromise.then(_ => {
isMusicPlaying = true;
musicBtn.textContent = '暂停音乐';
})
.catch(error => {
console.log('播放失败:', error);
alert('请先取消静音后再播放音乐');
});
}
}
isMusicPlaying = !isMusicPlaying;
});
// 静音控制
muteBtn.addEventListener('click', function() {
isMuted = !isMuted;
bgMusic.muted = isMuted;
videoBg.muted = isMuted;
muteBtn.textContent = isMuted ? '取消静音' : '静音';
// 如果取消静音且音乐未播放,尝试播放
if (!isMuted && !isMusicPlaying) {
bgMusic.play().then(() => {
isMusicPlaying = true;
musicBtn.textContent = '暂停音乐';
}).catch(e => {
console.log('播放失败:', e);
});
}
});
// 添加键盘快捷键
document.addEventListener('keydown', (e) => {
if (e.code === 'Space') {
e.preventDefault();
musicBtn.click();
} else if (e.code === 'KeyM') {
muteBtn.click();
}
});
// 页面加载完成后初始化
window.addEventListener('DOMContentLoaded', () => {
initMedia().finally(() => {
// 所有媒体加载完成后移除加载指示
loadingIndicator.style.opacity = '0';
setTimeout(() => {
loadingIndicator.remove();
}, 500);
});
});
</script>
</body>
</html>通过本文的详细介绍,我们完成了一个融合传统古诗与现代Web技术的沉浸式体验页面。从基础结构到高级交互,从样式设计到性能优化,每个环节都体现了"以用户为中心"的设计理念。希望这个项目能为您提供灵感,创造出更多优秀的文化传播作品。
传统文化与现代技术的结合有着无限可能,期待您能在此基础上继续探索,让更多经典作品以崭新的形式焕发生机。