好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 xhd335 于 2026-3-17 12:48 编辑
中小学古诗文学习工具 html代码
主要功能
分年级浏览:左侧列表按年级分组(如一年级上、七年级下等),每个篇目标题后附有作者,点击即可在右侧查看详细内容。
快速搜索:顶部搜索框支持按诗名或作者进行模糊搜索,输入关键词后回车或点击“搜索”按钮即可实时筛选篇目。
原文与译文对照:右侧上方以大字展示古诗文原文,每个字/词用独立卡片包裹,标点符号特殊处理,视觉清晰;下方区域显示对应的译文或注释,方便理解。
语音朗读
朗读原文:读出当前篇目的标题、朝代、作者及全部正文。
朗读译文:单独朗读译文内容。
基于浏览器内置的语音合成API,无需额外插件。
上下首切换
通过“上一首/下一首”按钮可在当前筛选结果中快速切换篇目,底部计数器实时显示当前进度(如“第 3 篇 / 共 35 篇”)。
界面设计
左右分栏布局,左侧为篇目列表(带滚动条),右侧为详情区。
配色采用暖色调(米白、棕褐),模拟纸质书质感,视觉舒适。
篇目列表选中态有高亮效果,右侧原文区字号较大,适合阅读。
底部有篇目计数,让用户清楚浏览范围。
数据特点
篇目覆盖小学一年级至初中九年级,按学期分册,与2026年最新教材同步。
包含古诗词、文言文、成语、谚语、现代诗(如《沁园春·雪》、《我爱这土地》)等,类型丰富。
每篇均包含:标题、作者、朝代、原文行数组、译文/注释。
使用方式
直接在浏览器中打开HTML文件即可运行,无需网络,所有数据内置。
支持键盘操作:在搜索框输入后按回车可执行搜索。
朗读功能需浏览器支持Web Speech API(现代浏览器均支持)。
这款小工具将教材古诗文集中呈现,并加入朗读辅助,对提升学习效率和兴趣很有帮助。如果你是家长或老师,也可以直接将它分享给学生使用。部分译文不全可以自行补充。
html代码过长,下面是主体代码展示。
[HTML] 纯文本查看 复制代码 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>一年级上册古诗文(2026最新教材)</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'Segoe UI', 'Microsoft YaHei', 'PingFang SC', 'Noto Sans CJK', system-ui, sans-serif;
background: #f3efe5;
min-width: 800px;
height: 100vh;
margin: 0;
padding: 0;
display: block;
}
.app-container {
width: 100%;
height: 100vh;
display: flex;
flex-direction: row;
background: #fffcf2;
border: none;
border-radius: 0;
box-shadow: none;
overflow: hidden;
}
.list-panel {
width: 380px;
background: #fcf9f2;
border-right: 2px solid #e6d7c2;
display: flex;
flex-direction: column;
overflow: hidden;
flex-shrink: 0;
}
.left-search-area { padding: 16px 16px 8px 16px; border-bottom: 1px solid #e0cfb8; }
.search-wrapper { display: flex; gap: 8px; width: 100%; }
.search-wrapper input {
flex: 1; padding: 12px 16px; border: 2px solid #dacdb6; border-radius: 48px;
font-size: 16px; background: white; outline: none; transition: 0.15s; color: #3e362e;
}
.search-wrapper input:focus { border-color: #b87c4b; box-shadow: 0 0 0 3px rgba(184,124,75,0.2); }
.search-wrapper button {
background: #b87c4b; border: none; border-radius: 48px; padding: 0 18px;
color: white; font-weight: 600; font-size: 15px; cursor: pointer;
display: flex; align-items: center; gap: 4px; border: 2px solid #a56e3f;
transition: 0.1s; box-shadow: 0 4px 6px rgba(0,0,0,0.05); white-space: nowrap;
}
.search-wrapper button:hover { background: #a56e3f; transform: scale(1.02); }
.list-header {
padding: 12px 20px 8px; font-weight: 600; color: #6b5843; font-size: 15px;
letter-spacing: 0.3px; background: #faf3e9; border-bottom: 1px solid #e0cfb8;
display: flex; justify-content: space-between;
}
.list-box {
flex: 1;
overflow-y: auto;
padding: 10px 12px 12px;
}
.grade-group {
margin-top: 12px; margin-bottom: 6px; font-weight: 700; font-size: 16px;
color: #8b6f50; padding-left: 8px; border-left: 5px solid #b87c4b;
background: #f5ede2; padding: 6px 12px; border-radius: 0 20px 20px 0;
}
.grade-group:first-of-type { margin-top: 0; }
.poem-item {
padding: 10px 14px; margin-bottom: 5px; margin-left: 8px; background: white;
border-radius: 14px; border: 1px solid #e0d1bd; cursor: pointer; transition: 0.08s;
box-shadow: 0 2px 4px rgba(0,0,0,0.02); font-size: 14px; display: flex;
align-items: center; gap: 6px;
}
.poem-item:hover { background: #f7ede1; border-color: #b87c4b; }
.poem-item.selected {
background: #eedbcb; border-color: #b87c4b; border-left: 5px solid #b87c4b; font-weight: 500;
}
.poem-title { font-weight: 600; color: #3e2f21; }
.poem-author { font-size: 12px; color: #8b755a; margin-left: auto; white-space: nowrap; }
/* 左侧底部计数器样式 */
.left-footer {
padding: 14px 16px;
border-top: 2px solid #e6d7c2;
background: #faf5ec;
text-align: center;
font-size: 15px;
color: #6b5843;
font-weight: 500;
letter-spacing: 0.3px;
}
.detail-panel {
flex: 1; padding: 24px 32px; overflow-y: auto; background: #fffdf9;
display: flex; flex-direction: column; gap: 20px; height: 100%; min-height: 0;
}
.original-section {
background: #fcf9f4; border-radius: 24px; padding: 28px 24px;
border: 1px solid #e7d9c6; box-shadow: inset 0 2px 6px rgba(0,0,0,0.02);
overflow-y: auto; flex: 1 1 auto; min-height: 0; display: flex;
flex-direction: column; align-items: center;
}
.poem-title-line {
font-size: 32px; font-weight: 600; color: #34281b; line-height: 1.3;
margin-bottom: 24px; text-align: left; width: fit-content;
display: flex; flex-wrap: wrap; justify-content: flex-start;
align-items: baseline; gap: 20px;
}
.poem-title-line .title-part { white-space: nowrap; }
.poem-title-line .author-part {
font-size: 24px; color: #8f7557; font-style: italic; font-weight: 400; white-space: nowrap;
}
.poem-line-block { margin-bottom: 16px; text-align: left; width: 100%; display: flex; flex-wrap: wrap; align-items: center; line-height: 1.8; }
.char-group {
display: inline-block; font-size: 23px; font-weight: 460; color: #2c241c;
line-height: 1.4; margin-right: 8px; border-bottom: 1px dotted #decbb4;
}
.char-group.punctuation { font-size: 23px; border-bottom: none; color: #6f5e4b; margin-right: 4px; }
.translation-section {
background: #f2ebe0; border-radius: 20px; padding: 22px;
border: 1px solid #dac8b0; flex-shrink: 0;
display: flex;
flex-direction: column;
gap: 16px;
}
.trans-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
}
.trans-label {
font-size: 18px; font-weight: 600; color: #5f4d38;
display: flex; align-items: center; gap: 8px;
white-space: nowrap;
}
.action-buttons {
display: flex;
gap: 10px;
align-items: center;
flex-wrap: wrap;
justify-content: flex-end;
}
.nav-btn {
background: #ede7db;
border: 2px solid #d2bb9e;
border-radius: 40px;
padding: 8px 16px;
font-weight: 600;
color: #4f3f30;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
font-size: 14px;
transition: 0.1s;
box-shadow: 0 2px 4px rgba(0,0,0,0.03);
white-space: nowrap;
}
.nav-btn:hover {
background: #dacdb6;
border-color: #b87c4b;
color: #2e281e;
}
.read-btn {
background: #2c5f2d !important;
border: 2px solid #1f4520 !important;
border-radius: 40px;
padding: 8px 16px;
font-weight: 600;
color: white !important;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
font-size: 14px;
transition: 0.1s;
box-shadow: 0 2px 4px rgba(0,0,0,0.03);
white-space: nowrap;
}
.read-btn:hover {
background: #1f4520 !important;
}
.trans-read-btn {
background: #2c5f2d;
border: 1px solid #1f4520;
border-radius: 30px;
padding: 8px 20px;
color: white;
font-weight: 500;
font-size: 14px;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 6px;
transition: 0.1s;
white-space: nowrap;
}
.trans-read-btn:hover {
background: #1f4520;
}
.trans-text {
font-size: 15px; line-height: 1.7; color: #3f3326; background: #fefcf8;
padding: 18px 24px; border-radius: 18px; border: 1px solid #d7c4ab; white-space: pre-wrap;
}
/* 右侧不再有页脚,所以移除原 .footer-info 样式 */
::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: #f3ede3; border-radius: 12px; }
::-webkit-scrollbar-thumb { background: #c9b59b; border-radius: 12px; border: 2px solid #f3ede3; }
::-webkit-scrollbar-thumb:hover { background: #b0875d; }
button { user-select: none; }
</style>
</head>
<body>
<div class="app-container" id="appContainer">
<div class="list-panel">
<div class="left-search-area">
<div class="search-wrapper">
<input type="text" id="searchInput" placeholder="搜索诗名、作者..." value="">
<button id="searchBtn">🔍 搜索</button>
</div>
</div>
<div class="list-header">📚 一年级上册古诗文(2026最新教材) <span id="totalCount">10篇</span></div>
<div class="list-box" id="poemListContainer"></div>
<!-- 左侧底部计数器,居中显示 -->
<div class="left-footer" id="leftFooterInfo">第 1 篇 / 共 10 篇</div>
</div>
<div class="detail-panel" id="detailPanel">
<div class="original-section" id="originalSection">
<div id="poemContent"></div>
</div>
<div class="translation-section">
<div class="trans-text" id="translationText"></div>
<div class="trans-header">
<div class="trans-label">📖 译 文 / 注 释</div>
<div class="action-buttons">
<button id="prevBtn" class="nav-btn">◀ 上一首</button>
<button id="nextBtn" class="nav-btn">下一首 ▶</button>
<button id="readBtn" class="read-btn">🔊 朗读原文</button>
<button id="transReadBtn" class="trans-read-btn">🔊 朗读译文</button>
</div>
</div>
</div>
<!-- 右侧原来的 footer-info 已移除 -->
</div>
</div>
<script>
(function() {
// ---------- 只保留一年级上册(2026最新教材)----------
const poemsByGrade = [
{ grade: "一年级(上)", list: [
{ title: "咏鹅", author: "骆宾王", dynasty: "唐", lines: ["鹅,鹅,鹅,", "曲项向天歌。", "白毛浮绿水,", "红掌拨清波。"], translation: "鹅呀鹅,弯着脖子向天唱歌。白色的羽毛浮在绿水,红掌拨动清澈的水波。" },
{ title: "江南", author: "汉乐府", dynasty: "汉", lines: ["江南可采莲,", "莲叶何田田。", "鱼戏莲叶间。", "鱼戏莲叶东,", "鱼戏莲叶西,", "鱼戏莲叶南,", "鱼戏莲叶北。"], translation: "江南可以采莲,莲叶多么茂盛。鱼儿在莲叶间嬉戏。鱼在莲叶东边游,鱼在莲叶西边游,鱼在莲叶南边游,鱼在莲叶北边游。" },
{ title: "悯农·其二", author: "李绅", dynasty: "唐", lines: ["锄禾日当午,", "汗滴禾下土。", "谁知盘中餐,", "粒粒皆辛苦。"], translation: "中午锄草,汗水滴进泥土。谁知道盘中的饭食,每一粒都那么辛苦。" },
{ title: "古朗月行(节选)", author: "李白", dynasty: "唐", lines: ["小时不识月,", "呼作白玉盘。", "又疑瑶台镜,", "飞在青云端。"], translation: "小时候不认识月亮,叫它白玉盘。又怀疑是瑶台镜,飞在青云端。" },
{ title: "风", author: "李峤", dynasty: "唐", lines: ["解落三秋叶,", "能开二月花。", "过江千尺浪,", "入竹万竿斜。"], translation: "能吹落三秋的叶,能开出二月的花。过江掀起千尺浪,入竹万竿都倾斜。" },
{ title: "对韵歌", author: "佚名", dynasty: "清", lines: ["云对雨,雪对风。", "花对树,鸟对虫。", "山清对水秀,", "柳绿对桃红。"], translation: "云对雨,雪对风。花对树,鸟对虫。山清对水秀,柳绿对桃红。" },
{ title: "数字诗", author: "佚名", dynasty: "清", lines: ["一片两片三四片,", "五片六片七八片。", "九片十片无数片,", "飞入梅花总不见。"], translation: "一片两片三四片,五片六片七八片。九片十片无数片,飞入梅花总不见。" },
{ title: "一年之计在于春", author: "谚语", dynasty: "民", lines: ["一年之计在于春,", "一日之计在于晨。", "一寸光阴一寸金,", "寸金难买寸光阴。"], translation: "一年的计划在于春天,一天的计划在于早晨。一寸光阴一寸金,寸金难买寸光阴。" },
{ title: "方向歌", author: "童谣", dynasty: "民", lines: ["早晨起来,面向太阳。", "前面是东,后面是西。", "左面是北,右面是南。"], translation: "早晨起来,面向太阳。前面是东,后面是西。左面是北,右面是南。" },
{ title: "成语积累", author: "童蒙", dynasty: "民", lines: ["种瓜得瓜,种豆得豆。", "前人栽树,后人乘凉。", "千里之行,始于足下。", "百尺竿头,更进一步。"], translation: "种什么得什么,前人的付出让后人受益,走千里路要从脚下开始,不要满足现状要更进一步。" }
]}
];
// 扁平化并保留年级信息
let poems = [];
poemsByGrade.forEach(gradeGroup => {
gradeGroup.list.forEach(p => {
poems.push({ ...p, grade: gradeGroup.grade });
});
});
// 更新总数显示
const totalSpan = document.getElementById('totalCount');
totalSpan.innerText = poems.length + '篇';
// 状态
let filteredPoems = poems.slice();
let selectedPoemId = 0;
const searchInput = document.getElementById('searchInput');
const searchBtn = document.getElementById('searchBtn');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
const readBtn = document.getElementById('readBtn');
const transReadBtn = document.getElementById('transReadBtn');
const poemListContainer = document.getElementById('poemListContainer');
const poemContent = document.getElementById('poemContent');
const translationText = document.getElementById('translationText');
const leftFooterInfo = document.getElementById('leftFooterInfo'); // 左侧底部计数器
function renderCharGroup(ch) {
const isPunct = /[,。?!、;:“”‘’]/.test(ch);
const cls = isPunct ? 'char-group punctuation' : 'char-group';
return `<span class="${cls}">${ch}</span>`;
}
function displayPoemDetails(poem) {
if (!poem) return;
let html = `<div class="poem-title-line"><span class="title-part">${poem.title}</span><span class="author-part">${poem.dynasty} · ${poem.author}</span></div>`;
const lines = poem.lines;
for (let i = 0; i < lines.length; i++) {
html += '<div class="poem-line-block">';
const chars = Array.from(lines[i]);
for (let j = 0; j < chars.length; j++) {
html += renderCharGroup(chars[j]);
}
html += '</div>';
}
poemContent.innerHTML = html;
translationText.innerText = poem.translation;
}
function renderList() {
poemListContainer.innerHTML = '';
let currentGrade = '';
filteredPoems.forEach((poem, idx) => {
if (poem.grade !== currentGrade) {
currentGrade = poem.grade;
const gradeDiv = document.createElement('div');
gradeDiv.className = 'grade-group';
gradeDiv.innerText = currentGrade;
poemListContainer.appendChild(gradeDiv);
}
const itemDiv = document.createElement('div');
itemDiv.className = `poem-item ${idx === selectedPoemId ? 'selected' : ''}`;
itemDiv.dataset.index = idx;
itemDiv.innerHTML = `<span class="poem-title">${poem.title}</span><span class="poem-author">${poem.author}</span>`;
itemDiv.addEventListener('click', () => {
selectedPoemId = idx;
renderList();
displayPoemDetails(poem);
updateFooter();
});
poemListContainer.appendChild(itemDiv);
});
if (filteredPoems.length === 0) {
poemListContainer.innerHTML = '<div style="padding:30px;text-align:center;color:#b7a48b;">📭 没有找到匹配篇目</div>';
poemContent.innerHTML = '';
translationText.innerText = '';
leftFooterInfo.innerText = '0 篇';
} else {
if (selectedPoemId >= filteredPoems.length) selectedPoemId = filteredPoems.length - 1;
displayPoemDetails(filteredPoems[selectedPoemId]);
updateFooter();
}
}
function updateFooter() {
if (filteredPoems.length === 0) leftFooterInfo.innerText = '无匹配';
else leftFooterInfo.innerText = `第 ${selectedPoemId + 1} 篇 / 共 ${filteredPoems.length} 篇`;
}
function filterPoems() {
const kw = searchInput.value.trim().toLowerCase();
filteredPoems = kw ? poems.filter(p => p.title.toLowerCase().includes(kw) || p.author.toLowerCase().includes(kw)) : poems.slice();
selectedPoemId = filteredPoems.length > 0 ? 0 : -1;
renderList();
}
function prevPoem() { if (filteredPoems.length) { selectedPoemId = (selectedPoemId - 1 + filteredPoems.length) % filteredPoems.length; renderList(); } }
function nextPoem() { if (filteredPoems.length) { selectedPoemId = (selectedPoemId + 1) % filteredPoems.length; renderList(); } }
function readOriginal() {
if (!filteredPoems.length) return;
const p = filteredPoems[selectedPoemId];
const text = `${p.title},${p.dynasty}·${p.author}。${p.lines.join('')}`;
const utter = new SpeechSynthesisUtterance(text);
utter.lang = 'zh-CN';
speechSynthesis.cancel();
speechSynthesis.speak(utter);
}
function readTranslation() {
if (!filteredPoems.length) return;
const p = filteredPoems[selectedPoemId];
const utter = new SpeechSynthesisUtterance(p.translation);
utter.lang = 'zh-CN';
speechSynthesis.cancel();
speechSynthesis.speak(utter);
}
searchBtn.addEventListener('click', filterPoems);
searchInput.addEventListener('keypress', e => e.key === 'Enter' && filterPoems());
prevBtn.addEventListener('click', prevPoem);
nextBtn.addEventListener('click', nextPoem);
readBtn.addEventListener('click', readOriginal);
transReadBtn.addEventListener('click', readTranslation);
renderList();
})();
</script>
</body>
</html>
|
免费评分
-
查看全部评分
|