1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
|
<!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默认边距,统一字体,设置页面背景和文字颜色,保证基础视觉一致性 */
body { margin:0; font-family: Arial, sans-serif; background:#fafafa; color:#222; }
/* 页面头部:绿色背景+白色文字,居中对齐,内边距控制高度和间距,突出标题 */
header { background:#4CAF50; color:white; padding:14px 20px; text-align:center; }
/* 导航栏:黑色背景,清除浮动(避免子元素浮动导致容器高度塌陷) */
nav { background:#333; overflow:hidden; }
/* 导航链接:左浮动实现横向排列,白色文字,内边距扩大点击区域,去除下划线 */
nav a {
float:left; display:block; color:white;
text-align:center; padding:14px 16px;
text-decoration:none; transition:0.25s; /* hover时背景色过渡,提升交互感 */
}
/* 导航交互状态:hover(鼠标悬停)和active(当前选中)时变灰底黑字,明确当前位置 */
nav a:hover, nav a.active { background-color:#ddd; color:black; }
/* 主内容区:内边距控制间距,最小高度60vh(确保内容过少时,底部footer不向上偏移) */
main { padding:20px; min-height:60vh; }
/* ====================== 页面功能区块(section)样式 ====================== */
/* 所有功能区块默认隐藏(通过show类控制显示),内边距控制内部间距 */
section { display:none; padding:20px 10px; }
/* 显示状态的区块:添加淡入动画(从下往上+透明到不透明),提升切换流畅度 */
section.show {
display:block;
animation:fadeIn 0.35s ease; /* 调用fadeIn关键帧,0.35秒完成,缓动效果更自然 */
}
/* ====================== Tab切换组件样式 ====================== */
/* Tab按钮容器:底部边框分隔内容,底部间距避免与内容重叠 */
.tab { overflow:hidden; border-bottom:1px solid #ccc; margin-bottom:10px; }
/* Tab按钮:浅灰背景,无边框,内边距控制大小,右侧间距分隔按钮,手型光标提示可点击 */
.tab button {
background-color:#f1f1f1; border:none; outline:none;
padding:10px 18px; margin-right:6px; cursor:pointer;
transition:0.2s; /* 背景色变化过渡,增强交互反馈 */
}
/* 激活状态的Tab按钮:深灰背景,明确当前选中的Tab */
.tab button.active { background-color:#ccc; }
/* ====================== Tab内容区样式 ====================== */
/* Tab内容默认隐藏,通过show类控制显示 */
.tabcontent { display:none; padding:10px 0; }
/* 显示状态的Tab内容:block显示,与隐藏状态形成切换 */
.tabcontent.show { display:block; }
/* ====================== 模态弹窗(Modal)样式 ====================== */
/* 弹窗遮罩层:默认隐藏,固定定位全屏覆盖,层级1000(确保在所有元素之上),半透明黑背景 */
.modal {
display:none; position:fixed; z-index:1000;
left:0; top:0; width:100%; height:100%;
background:rgba(0,0,0,0.45); /* 半透明遮罩,突出弹窗 */
}
/* 弹窗内容区:白色背景,水平居中(10%上下边距),最大宽度限制,圆角优化视觉,初始缩放0.85 */
.modal-content {
background:white; margin:10% auto; padding:18px;
max-width:420px; border-radius:8px; /* 圆角减少尖锐感 */
transform:scale(0.85); /* 初始小尺寸,为弹出动画做准备 */
transition:transform 0.25s ease; /* 缩放过渡,实现弹出效果 */
}
/* 弹窗显示时:内容区恢复原尺寸(1.0),完成弹出动画 */
.modal.show .modal-content { transform:scale(1); }
/* 弹窗关闭按钮:右浮动,粗体,手型光标,方便用户识别和点击 */
.close { float:right; font-weight:bold; cursor:pointer; }
/* ====================== 图片轮播(Carousel)样式 ====================== */
/* 轮播容器:相对定位(作为图片绝对定位的父容器),最大宽度限制,固定高度,溢出隐藏(裁剪超出部分) */
.carousel {
position:relative; max-width:600px; margin:12px auto;
height:200px; overflow:hidden; border-radius:8px;
background:#ddd; /* 加载时显示浅灰背景,避免空白 */
}
/* 轮播图片:绝对定位(所有图片重叠在同一位置),宽高100%,object-fit:cover(填满容器且不拉伸变形) */
.carousel img {
width:100%; height:100%; object-fit:cover;
display:block; position:absolute; top:0; left:0;
opacity:0; /* 初始透明,为淡入淡出做准备 */
transition:opacity 0.8s ease; /* 透明度过渡,实现平滑切换 */
}
/* 显示状态的图片:完全不透明,层级2(确保在其他图片之上) */
.carousel img.show { opacity:1; z-index:2; }
/* ====================== 拖拽列表(Drag List)样式 ====================== */
/* 列表容器:清除默认列表样式(无项目符号、无左内边距),最大宽度限制 */
#dragList { list-style:none; padding-left:0; max-width:600px; }
/* 列表项:上下间距,内边距,边框,白色背景,手型光标(提示可拖拽),弹性布局(内容左、按钮右) */
#dragList li {
margin:6px 0; padding:10px; border:1px solid #ccc;
background:#fff; cursor:move; /* 移动光标,明确可拖拽 */
display:flex; justify-content:space-between; align-items:center;
border-radius:6px; /* 圆角优化 */
}
/* 列表项中的删除按钮:左侧间距,避免与文字挤在一起 */
#dragList button { margin-left:8px; }
/* ====================== 表单(Form)样式 ====================== */
/* 表单元素统一样式:内边距,顶部间距,宽度100%(自适应容器),box-sizing:border-box(padding不撑大宽度) */
input, select, textarea, button {
padding:8px; margin-top:6px; width:100%;
box-sizing:border-box; /* 确保元素宽度不超出容器 */
}
/* 表单标签:块级显示(独占一行),顶部间距,粗体,提升可读性 */
label { display:block; margin-top:10px; font-weight:600; }
/* ====================== 页脚(Footer)样式 ====================== */
/* 页脚:黑色背景,白色文字,居中对齐,内边距,顶部间距(与主内容区分隔) */
footer {
background:#333; color:#fff; text-align:center;
padding:12px; margin-top:20px;
}
/* ====================== 动画关键帧定义 ====================== */
/* 淡入动画:从透明(opacity:0)+ 向下偏移6px,到不透明(opacity:1)+ 无偏移,实现自然过渡 */
@keyframes fadeIn {
from {opacity:0; transform:translateY(6px);}
to {opacity:1; transform:none;}
}
/* ====================== 响应式设计(适配移动端) ====================== */
/* 屏幕宽度≤600px时(手机等小屏设备)执行以下样式 */
@media screen and (max-width:600px) {
/* 导航链接:取消浮动,宽度100%(独占一行),文字左对齐,左侧内边距(优化点击体验) */
nav a { float:none; width:100%; text-align:left; padding-left:14px; }
/* 轮播容器:高度减小(适配小屏,避免图片过高) */
.carousel { height:160px; }
}
</style>
</head>
<body>
<!-- 页面头部:展示网站主标题,强化品牌感 -->
<header>
<h1>完整前端示例网站</h1>
</header>
<!-- 导航栏:单页切换入口,data-target属性关联目标功能区块的id -->
<nav>
<a href="#" class="nav-link active" data-target="home">首页</a>
<a href="#" class="nav-link" data-target="tab">Tab 示例</a>
<a href="#" class="nav-link" data-target="modal">弹窗示例</a>
<a href="#" class="nav-link" data-target="carousel">轮播示例</a>
<a href="#" class="nav-link" data-target="form">表单示例</a>
<a href="#" class="nav-link" data-target="list">拖拽列表</a>
</nav>
<!-- 主内容区:包含所有功能模块,默认仅显示首页(加show类) -->
<main>
<!-- 1. 首页区块:网站介绍,默认显示 -->
<section id="home" class="show">
<h2>首页</h2>
<p>欢迎来到完整前端示例网站。使用顶部导航即可切换不同示例页面,下面是一些交互组件演示。</p>
</section>
<!-- 2. Tab切换区块:展示多内容切换功能,默认隐藏 -->
<section id="tab">
<h2>Tab 切换</h2>
<!-- Tab按钮容器:存放3个切换按钮 -->
<div class="tab">
<button class="tablinks active" onclick="openTab(event,'Tab1')">Tab 1</button>
<button class="tablinks" onclick="openTab(event,'Tab2')">Tab 2</button>
<button class="tablinks" onclick="openTab(event,'Tab3')">Tab 3</button>
</div>
<!-- Tab内容区:3个内容面板,默认显示Tab1(加show类) -->
<div id="Tab1" class="tabcontent show"><p>这是 Tab 1 的内容示例。</p></div>
<div id="Tab2" class="tabcontent"><p>这是 Tab 2 的内容示例。</p></div>
<div id="Tab3" class="tabcontent"><p>这是 Tab 3 的内容示例。</p></div>
</section>
<!-- 3. 模态弹窗区块:展示弹窗交互,默认隐藏 -->
<section id="modal">
<h2>模态弹窗</h2>
<button onclick="openModal()">打开弹窗</button>
<!-- 弹窗容器:默认隐藏,aria-hidden="true"(无障碍属性:告知屏幕阅读器当前元素隐藏) -->
<div id="myModal" class="modal" aria-hidden="true">
<div class="modal-content">
<!-- 关闭按钮:aria-label="关闭"(无障碍:给屏幕阅读器提示按钮功能) -->
<span class="close" onclick="closeModal()" aria-label="关闭">×</span>
<h3>示例弹窗</h3>
<p>这是一个带动画的模态弹窗示例。点击空白处或 × 可关闭。</p>
</div>
</div>
</section>
<!-- 4. 图片轮播区块:展示自动切换图片功能,默认隐藏 -->
<section id="carousel">
<h2>图片轮播</h2>
<!-- 轮播容器:aria-live="polite"(无障碍:内容变化时,屏幕阅读器会主动播报) -->
<div class="carousel" aria-live="polite">
<!-- 轮播图片:alt属性(无障碍:描述图片内容,图片加载失败时也能理解含义) -->
<img src="https://via.placeholder.com/800x400?text=Slide+1" class="carousel-item show" alt="幻灯片1">
<img src="https://via.placeholder.com/800x400?text=Slide+2" class="carousel-item" alt="幻灯片2">
<img src="https://via.placeholder.com/800x400?text=Slide+3" class="carousel-item" alt="幻灯片3">
</div>
</section>
<!-- 5. 表单示例区块:展示表单验证与提交,默认隐藏;novalidate(关闭浏览器默认验证,用自定义逻辑) -->
<section id="form">
<h2>表单示例</h2>
<form id="signupForm" novalidate>
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required placeholder="请输入用户名">
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required placeholder="输入邮箱地址">
<label for="message">留言:</label>
<textarea id="message" name="message" rows="4" placeholder="写点什么..."></textarea>
<button type="submit" style="margin-top:12px;">提交</button>
</form>
<!-- 表单结果提示:默认绿色文字,用于显示成功/失败信息 -->
<p id="formMessage" style="margin-top:10px;color:green;"></p>
</section>
<!-- 6. 拖拽列表区块:展示拖拽排序、添加/删除功能,默认隐藏 -->
<section id="list">
<h2>拖拽列表(可添加/删除/拖动排序)</h2>
<div style="max-width:600px;">
<!-- 列表项输入框:用于输入新的列表内容 -->
<input type="text" id="itemInput" placeholder="输入列表项">
<!-- 添加按钮:触发添加列表项的逻辑 -->
<button onclick="addItem()" style="margin-top:8px;">添加项</button>
<!-- 拖拽列表容器:aria-label="可拖拽列表"(无障碍:描述列表功能) -->
<ul id="dragList" aria-label="可拖拽列表" style="margin-top:12px;">
<!-- 初始列表项:draggable="true"(开启拖拽功能) -->
<li draggable="true">示例项 1 <button onclick="removeItem(this)">删除</button></li>
<li draggable="true">示例项 2 <button onclick="removeItem(this)">删除</button></li>
</ul>
</div>
<!-- 操作提示:浅灰色文字,告知用户可拖拽排序 -->
<p style="margin-top:8px;color:#666;">提示:按住某项并拖动以更改顺序。</p>
</section>
</main>
<!-- 页脚:展示版权信息,固定在页面底部 -->
<footer>
<p>© 2025 完整前端示例网站</p>
</footer>
<script>
/* ====================== 1. 单页导航切换(核心:点击导航显示对应区块) ====================== */
// 获取所有导航链接(class="nav-link")
const navLinks = document.getElementsByClassName('nav-link');
// 遍历每个导航链接,为其绑定点击事件
for (let link of navLinks) {
link.addEventListener('click', function(e) {
// 阻止a标签默认跳转行为(默认会跳转到#对应的页面顶部,这里需要自定义切换逻辑)
e.preventDefault();
// 步骤1:重置所有导航链接的active状态(取消所有选中样式)
for (let l of navLinks) l.classList.remove('active');
// 步骤2:给当前点击的导航链接添加active状态(标记为当前选中)
this.classList.add('active');
// 步骤3:获取目标功能区块的id(从data-target属性中读取,如"home"、"tab")
const target = this.dataset.target;
// 步骤4:获取所有功能区块(section标签)
const sections = document.getElementsByTagName('section');
// 步骤5:重置所有区块的show状态(隐藏所有区块)
for (let s of sections) s.classList.remove('show');
// 步骤6:显示目标区块(给目标section添加show类,触发显示和淡入动画)
const targetSection = document.getElementById(target);
if (targetSection) targetSection.classList.add('show');
// 可选优化:切换区块时,平滑滚动到页面顶部(提升用户体验)
window.scrollTo({ top: 0, behavior: 'smooth' });
});
}
/* ====================== 2. Tab切换功能 ====================== */
// evt:点击事件对象(包含点击相关信息);tabName:目标Tab内容的id(如"Tab1")
function openTab(evt, tabName) {
// 步骤1:隐藏所有Tab内容(移除所有tabcontent的show类)
const allTabContents = document.getElementsByClassName('tabcontent');
for (let tabContent of allTabContents) {
tabContent.classList.remove('show');
}
// 步骤2:重置所有Tab按钮的active状态(取消所有按钮的选中样式)
// 获取当前点击按钮的父容器(.tab),再找到容器内所有按钮
const tabButtonParent = evt.currentTarget.parentElement;
const allTabButtons = tabButtonParent.getElementsByTagName('button');
for (let button of allTabButtons) {
button.classList.remove('active');
}
// 步骤3:显示目标Tab内容(给目标tabcontent添加show类)
const targetTabContent = document.getElementById(tabName);
if (targetTabContent) targetTabContent.classList.add('show');
// 步骤4:给当前点击的Tab按钮添加active状态(标记为选中)
evt.currentTarget.classList.add('active');
}
/* ====================== 3. 模态弹窗功能 ====================== */
// 打开弹窗
function openModal() {
const modal = document.getElementById('myModal');
modal.style.display = 'block'; // 显示遮罩层
modal.classList.add('show'); // 添加show类,触发弹窗弹出动画
modal.setAttribute('aria-hidden', 'false'); // 无障碍:告知屏幕阅读器弹窗已显示
}
// 关闭弹窗
function closeModal() {
const modal = document.getElementById('myModal');
modal.classList.remove('show'); // 移除show类,取消弹出状态
modal.style.display = 'none'; // 隐藏遮罩层
modal.setAttribute('aria-hidden', 'true'); // 无障碍:告知屏幕阅读器弹窗已隐藏
}
// 点击弹窗外部遮罩层时关闭弹窗
window.addEventListener('click', function(e) {
const modal = document.getElementById('myModal');
// 若点击的是遮罩层本身(而非弹窗内容),则关闭弹窗
if (e.target === modal) {
closeModal();
}
});
/* ====================== 4. 图片轮播功能 ====================== */
let slideIndex = 0; // 记录当前显示的图片索引(初始为0)
const slides = document.getElementsByClassName('carousel-item'); // 获取所有轮播图片
// 轮播核心函数:切换并显示图片
function showSlides() {
// 步骤1:隐藏所有图片(移除所有图片的show类)
for (let slide of slides) {
slide.classList.remove('show');
}
// 步骤2:更新图片索引(切换到下一张)
slideIndex++;
// 若索引超出图片总数,重置为1(实现循环播放)
if (slideIndex > slides.length) {
slideIndex = 1;
}
// 步骤3:显示当前索引对应的图片(给目标图片添加show类,触发淡入效果)
// 注意:数组索引从0开始,slideIndex从1开始,需减1匹配
slides[slideIndex - 1].classList.add('show');
// 步骤4:设置定时器,3秒后调用自身,实现自动轮播
setTimeout(showSlides, 3000);
}
// 页面加载后立即启动轮播
showSlides();
/* ====================== 5. 表单验证与提交功能 ====================== */
// 给表单绑定submit事件(表单提交时触发)
document.getElementById('signupForm').addEventListener('submit', function(e) {
e.preventDefault(); // 阻止表单默认提交(避免页面刷新)
// 获取输入值并去除前后空格(避免空字符导致的无效提交)
const username = document.getElementById('username').value.trim();
const email = document.getElementById('email').value.trim();
const formMessage = document.getElementById('formMessage'); // 结果提示元素
// 简单验证逻辑:检查用户名和邮箱是否为空
if (!username) {
formMessage.style.color = 'red'; // 错误信息用红色
formMessage.textContent = '请填写用户名。'; // 提示用户补全信息
return; // 验证失败,终止后续逻辑
}
if (!email) {
formMessage.style.color = 'red';
formMessage.textContent = '请填写邮箱。';
return;
}
// 验证通过:显示成功信息
formMessage.style.color = 'green'; // 成功信息用绿色
formMessage.textContent = `提交成功!用户名: ${username},邮箱: ${email}`;
// 可选:验证通过后清空表单(按需启用)
// this.reset();
});
/* ====================== 6. 拖拽列表功能(添加/删除/排序) ====================== */
const dragList = document.getElementById('dragList'); // 获取拖拽列表容器
let draggedItem = null; // 存储被拖拽的列表项(初始为null)
// 1. 拖拽开始事件(用户按住列表项开始拖动时触发)
dragList.addEventListener('dragstart', function(e) {
// 找到被拖拽的列表项(若点击的是按钮等子元素,需向上找到最近的li)
let targetItem = e.target;
while (targetItem && targetItem.tagName !== 'LI') {
targetItem = targetItem.parentElement;
}
// 若找到有效的li,记录为被拖拽项
if (targetItem && targetItem.tagName === 'LI') {
draggedItem = targetItem;
// 部分浏览器需要设置dataTransfer数据才能正常触发拖拽(兼容处理)
try {
e.dataTransfer.setData('text/plain', 'dragging');
} catch (err) {
console.log('拖拽数据设置失败:', err);
}
}
});
// 2. 拖拽经过事件(拖拽过程中鼠标经过列表时触发)
dragList.addEventListener('dragover', function(e) {
e.preventDefault(); // 必须阻止默认行为,否则无法触发drop事件(拖拽释放)
});
// 3. 拖拽释放事件(用户松开鼠标,完成拖拽时触发)
dragList.addEventListener('drop', function(e) {
e.preventDefault(); // 阻止默认行为(避免浏览器打开链接等意外操作)
if (!draggedItem) return; // 若没有被拖拽项,直接返回
// 找到释放位置对应的目标列表项(若点击的是子元素,向上找到最近的li)
let targetItem = e.target;
while (targetItem && targetItem !== dragList && targetItem.tagName !== 'LI') {
targetItem = targetItem.parentElement;
}
// 处理不同释放位置:
if (!targetItem || targetItem === dragList) {
// 情况1:释放到列表空白处 → 把被拖拽项放到列表末尾
dragList.appendChild(draggedItem);
} else if (targetItem.tagName === 'LI' && targetItem !== draggedItem) {
// 情况2:释放到另一个列表项上 → 把被拖拽项插入到目标项后面
dragList.insertBefore(draggedItem, targetItem.nextSibling);
}
// 重置被拖拽项(完成一次拖拽后清空记录)
draggedItem = null;
});
// 4. 删除列表项功能(btn:被点击的删除按钮)
function removeItem(btn) {
if (!btn) return;
// 找到按钮的父元素(即要删除的列表项),并移除
const itemToRemove = btn.closest('li'); // closest:向上找到最近的li
if (itemToRemove) itemToRemove.remove();
}
// 5. 添加列表项功能
function addItem() {
// 获取输入值并去除前后空格(避免空项)
const inputValue = document.getElementById('itemInput').value.trim();
if (!inputValue) return; // 输入为空,直接返回
// 步骤1:创建新的列表项(li元素)
const newListItem = document.createElement('li');
newListItem.setAttribute('draggable', 'true'); // 开启新项的拖拽功能
// 步骤2:创建列表项内容(文本+删除按钮)
const textSpan = document.createElement('span');
textSpan.textContent = inputValue; // 文本内容为输入值
const deleteBtn = document.createElement('button');
deleteBtn.type = 'button';
deleteBtn.textContent = '删除';
// 给删除按钮绑定点击事件(点击时删除当前列表项)
deleteBtn.addEventListener('click', function() {
newListItem.remove();
});
// 步骤3:将文本和按钮添加到新列表项中
newListItem.appendChild(textSpan);
newListItem.appendChild(deleteBtn);
// 步骤4:将新列表项添加到列表末尾
dragList.appendChild(newListItem);
// 步骤5:清空输入框(方便用户继续添加)
document.getElementById('itemInput').value = '';
}
/* ====================== 无障碍兼容:页面加载完成后的初始化 ====================== */
// 确保页面DOM完全加载后执行(避免元素未加载导致的错误)
document.addEventListener('DOMContentLoaded', function() {
// 此处主要为兼容:确保初始列表项的删除按钮能正常工作(因初始按钮用了onclick="removeItem(this)")
// 无需额外代码,因removeItem函数已全局定义,onclick可直接调用
});
</script>
</body>
</html>
|