功能特点

  1. 添加留言:用户可以输入昵称和留言内容并提交。
  2. 实时显示:新留言会立即显示在列表的顶部。
  3. 时间戳:每条留言都带有精确的发布时间。
  4. 响应式设计:在桌面、平板和手机上都能良好显示。
  5. 交互反馈:提交后有成功提示,输入框有焦点状态。
  6. 数据持久化:使用 localStorage 保存留言,刷新页面后留言不会丢失。
  7. 清空功能:提供了一个清空所有留言的按钮(需要二次确认)。
  8. 现代化UI:使用了 CSS3 的渐变、阴影、过渡动画等效果。

最终效果预览

这是一个静态的 GIF 预览,展示了添加留言、刷新页面数据保留以及清空留言的功能。

html5 css3网页留言板
(图片来源网络,侵删)

代码实现

您只需要将以下三个代码块分别保存为 .html, .css, 和 .js 文件,并将它们放在同一个文件夹下,然后用浏览器打开 index.html 即可运行。

HTML 代码 (index.html)

这是页面的结构,包含标题、输入表单和留言列表容器。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">HTML5 & CSS3 留言板</title>
    <link rel="stylesheet" href="style.css">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet">
</head>
<body>
    <div class="container">
        <header>
            <h1>✍️ 我的留言板</h1>
            <p>分享你的想法,与世界互动</p>
        </header>
        <main>
            <!-- 留言输入表单 -->
            <section class="message-form">
                <form id="messageForm">
                    <div class="form-group">
                        <input type="text" id="nickname" placeholder="请输入你的昵称" required maxlength="20">
                    </div>
                    <div class="form-group">
                        <textarea id="content" placeholder="写下你想说的话..." required maxlength="200"></textarea>
                    </div>
                    <button type="submit" id="submitBtn">发布留言</button>
                </form>
            </section>
            <!-- 操作提示和清空按钮 -->
            <section class="actions">
                <div id="successMessage" class="success-message">
                    留言发布成功!
                </div>
                <button id="clearBtn" class="clear-btn">清空所有留言</button>
            </section>
            <!-- 留言列表 -->
            <section class="message-list" id="messageList">
                <!-- 留言将通过 JavaScript 动态添加到这里 -->
                <div class="message-item">
                    <div class="message-header">
                        <span class="nickname">示例用户</span>
                        <span class="time">2025-10-27 10:30:00</span>
                    </div>
                    <div class="message-content">
                        欢迎使用这个留言板!这是第一条示例留言,你可以删除它或添加你自己的留言。
                    </div>
                </div>
            </section>
        </main>
    </div>
    <script src="script.js"></script>
</body>
</html>

CSS 代码 (style.css)

这是样式表,负责页面的所有视觉呈现,包括布局、颜色、字体和动画。

/* --- 全局样式和变量 --- */
:root {
    --primary-color: #007bff;
    --secondary-color: #6c757d;
    --success-color: #28a745;
    --danger-color: #dc3545;
    --light-bg: #f8f9fa;
    --white: #ffffff;
    --text-color: #333;
    --border-color: #dee2e6;
    --shadow-sm: 0 2px 4px rgba(0,0,0,0.05);
    --shadow-md: 0 4px 8px rgba(0,0,0,0.1);
    --shadow-lg: 0 8px 16px rgba(0,0,0,0.1);
    --border-radius: 8px;
    --transition: all 0.3s ease;
}
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
body {
    font-family: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    background: linear-gradient(135deg, #e0f7fa 0%, #bbdefb 100%);
    color: var(--text-color);
    line-height: 1.6;
    min-height: 100vh;
}
.container {
    max-width: 800px;
    margin: 2rem auto;
    padding: 0 1rem;
}
/* --- 头部样式 --- */
header {
    text-align: center;
    margin-bottom: 2rem;
    animation: fadeInDown 0.8s ease-out;
}
header h1 {
    font-size: 2.5rem;
    color: var(--primary-color);
    margin-bottom: 0.5rem;
}
header p {
    font-size: 1.1rem;
    color: var(--secondary-color);
}
/* --- 主要内容区域 --- */
main {
    background: var(--white);
    border-radius: var(--border-radius);
    box-shadow: var(--shadow-lg);
    padding: 2rem;
    animation: fadeIn 1s ease-out;
}
/* --- 表单样式 --- */
.message-form {
    margin-bottom: 2rem;
}
.form-group {
    margin-bottom: 1rem;
}
.form-group input,
.form-group textarea {
    width: 100%;
    padding: 12px 15px;
    border: 2px solid var(--border-color);
    border-radius: var(--border-radius);
    font-size: 1rem;
    font-family: inherit;
    transition: var(--transition);
}
.form-group input:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}
.form-group textarea {
    resize: vertical;
    min-height: 100px;
}
#submitBtn {
    display: block;
    width: 100%;
    padding: 12px;
    background: linear-gradient(to right, var(--primary-color), #0056b3);
    color: var(--white);
    border: none;
    border-radius: var(--border-radius);
    font-size: 1.1rem;
    font-weight: 500;
    cursor: pointer;
    transition: var(--transition);
}
#submitBtn:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}
#submitBtn:active {
    transform: translateY(0);
}
/* --- 操作区域样式 --- */
.actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 2rem;
    flex-wrap: wrap;
    gap: 1rem;
}
.success-message {
    background-color: var(--success-color);
    color: var(--white);
    padding: 10px 15px;
    border-radius: var(--border-radius);
    opacity: 0;
    transform: translateY(-10px);
    transition: var(--transition);
}
.success-message.show {
    opacity: 1;
    transform: translateY(0);
}
.clear-btn {
    padding: 8px 16px;
    background-color: var(--danger-color);
    color: var(--white);
    border: none;
    border-radius: var(--border-radius);
    cursor: pointer;
    transition: var(--transition);
    font-size: 0.9rem;
}
.clear-btn:hover {
    background-color: #c82333;
    transform: translateY(-1px);
}
/* --- 留言列表样式 --- */
.message-list {
    max-height: 600px;
    overflow-y: auto;
    padding-right: 10px;
}
.message-list::-webkit-scrollbar {
    width: 8px;
}
.message-list::-webkit-scrollbar-track {
    background: var(--light-bg);
    border-radius: 10px;
}
.message-list::-webkit-scrollbar-thumb {
    background: var(--secondary-color);
    border-radius: 10px;
}
.message-list::-webkit-scrollbar-thumb:hover {
    background: #5a6268;
}
.message-item {
    background: var(--light-bg);
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    padding: 1.5rem;
    margin-bottom: 1rem;
    animation: slideIn 0.5s ease-out;
    transition: var(--transition);
}
.message-item:hover {
    box-shadow: var(--shadow-md);
    transform: translateX(5px);
}
.message-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.8rem;
}
.nickname {
    font-weight: 700;
    color: var(--primary-color);
    font-size: 1.1rem;
}
.time {
    font-size: 0.85rem;
    color: var(--secondary-color);
}
.message-content {
    color: var(--text-color);
    line-height: 1.7;
    white-space: pre-wrap; /* 保留换行 */
}
/* --- 空状态样式 --- */
.empty-state {
    text-align: center;
    padding: 3rem;
    color: var(--secondary-color);
}
.empty-state p {
    font-size: 1.2rem;
}
/* --- 动画 --- */
@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}
@keyframes fadeInDown {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}
@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateX(-30px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}
/* --- 响应式设计 --- */
@media (max-width: 600px) {
    header h1 {
        font-size: 2rem;
    }
    main {
        padding: 1.5rem;
    }
    .message-item {
        padding: 1rem;
    }
    .actions {
        flex-direction: column;
        align-items: stretch;
    }
    .clear-btn {
        width: 100%;
    }
}

JavaScript 代码 (script.js)

这是脚本文件,负责处理所有交互逻辑,如添加、显示、保存和清空留言。

html5 css3网页留言板
(图片来源网络,侵删)
document.addEventListener('DOMContentLoaded', () => {
    // --- DOM 元素 ---
    const messageForm = document.getElementById('messageForm');
    const nicknameInput = document.getElementById('nickname');
    const contentInput = document.getElementById('content');
    const messageList = document.getElementById('messageList');
    const clearBtn = document.getElementById('clearBtn');
    const successMessage = document.getElementById('successMessage');
    // --- 初始化 ---
    // 从 localStorage 加载留言
    let messages = JSON.parse(localStorage.getItem('guestbook_messages')) || [];
    // 如果是第一次加载(没有本地数据),则显示示例留言
    if (messages.length === 0) {
        const initialMessage = {
            id: Date.now(), // 使用时间戳作为唯一ID
            nickname: '示例用户',
            content: '欢迎使用这个留言板!这是第一条示例留言,你可以删除它或添加你自己的留言。',
            time: new Date().toLocaleString('zh-CN')
        };
        messages.push(initialMessage);
        localStorage.setItem('guestbook_messages', JSON.stringify(messages));
    }
    // 渲染所有留言
    renderMessages();
    // --- 事件监听器 ---
    messageForm.addEventListener('submit', handleSubmit);
    clearBtn.addEventListener('click', handleClear);
    // --- 函数定义 ---
    /**
     * 处理表单提交
     */
    function handleSubmit(e) {
        e.preventDefault(); // 阻止表单默认提交行为
        const nickname = nicknameInput.value.trim();
        const content = contentInput.value.trim();
        if (nickname && content) {
            const newMessage = {
                id: Date.now(), // 使用时间戳作为唯一ID
                nickname: nickname,
                content: content,
                time: new Date().toLocaleString('zh-CN')
            };
            // 添加到留言数组的开头
            messages.unshift(newMessage);
            // 保存到 localStorage
            saveMessages();
            // 重新渲染留言列表
            renderMessages();
            // 清空输入框
            messageForm.reset();
            nicknameInput.focus(); // 将焦点放回昵称输入框
            // 显示成功提示
            showSuccessMessage();
        }
    }
    /**
     * 渲染所有留言到页面上
     */
    function renderMessages() {
        // 清空当前列表(保留一个空的容器)
        messageList.innerHTML = '';
        if (messages.length === 0) {
            messageList.innerHTML = '<div class="empty-state"><p>还没有留言,快来留下第一条吧!</p></div>';
            return;
        }
        // 遍历留言数组并创建DOM元素
        messages.forEach(message => {
            const messageItem = document.createElement('div');
            messageItem.className = 'message-item';
            messageItem.innerHTML = `
                <div class="message-header">
                    <span class="nickname">${escapeHtml(message.nickname)}</span>
                    <span class="time">${message.time}</span>
                </div>
                <div class="message-content">${escapeHtml(message.content)}</div>
            `;
            messageList.prepend(messageItem); // 使用 prepend 将新留言添加到顶部
        });
    }
    /**
     * 处理清空留言操作
     */
    function handleClear() {
        if (messages.length === 0) {
            alert('留言板已经是空的了!');
            return;
        }
        // 使用 window.confirm 进行二次确认
        const isConfirmed = confirm('确定要清空所有留言吗?此操作不可恢复!');
        if (isConfirmed) {
            messages = [];
            saveMessages();
            renderMessages();
        }
    }
    /**
     * 将留言数据保存到 localStorage
     */
    function saveMessages() {
        localStorage.setItem('guestbook_messages', JSON.stringify(messages));
    }
    /**
     * 显示成功提示,并在几秒后自动隐藏
     */
    function showSuccessMessage() {
        successMessage.classList.add('show');
        setTimeout(() => {
            successMessage.classList.remove('show');
        }, 3000); // 3秒后隐藏
    }
    /**
     * 防止XSS攻击的简单转义函数
     * @param {string} str - 需要转义的字符串
     * @returns {string} - 转义后的安全字符串
     */
    function escapeHtml(str) {
        return str
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;");
    }
});

如何运行

  1. 创建文件:在你的电脑上创建一个新文件夹,guestbook
  2. 保存代码:将上面的 HTML、CSS 和 JavaScript 代码分别复制并保存到以下文件中,确保文件名正确:
    • guestbook/index.html
    • guestbook/style.css
    • guestbook/script.js
  3. 打开网页:用 Chrome、Firefox、Edge 等现代浏览器打开 index.html 文件。

你就拥有了一个功能完整、设计美观的留言板了!你可以尝试添加留言、刷新页面、清空留言,感受它的功能。

html5 css3网页留言板
(图片来源网络,侵删)