聊天网站半成品,前端
2026-09-07 20:04:18
发布于:北京
代码,复制到文本文档,文件,另存为,xxx.html,退出,点开HTML,(仅能演示)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>简易聊天贴吧系统</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Microsoft Yahei", system-ui, sans-serif;
}
html, body {
width: 100%;
height: 100%;
overflow: hidden;
background: #fff;
}
/* ========== 整体容器:铺满全屏 ========== */
.app-container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* ========== 顶部导航栏 ========== */
.header {
height: 56px;
border-bottom: 1px solid #888;
display: flex;
align-items: center;
padding: 0 16px;
flex-shrink: 0;
}
.avatar {
width: 34px;
height: 34px;
border-radius: 50%;
background: #ccc;
border: 1px solid #666;
margin-right: 16px;
}
.tabs {
display: flex;
gap: 28px;
font-size: 20px;
}
.tabs span {
cursor: pointer;
padding-bottom: 2px;
}
.tabs .active {
border-bottom: 2px solid #f7931e;
color: #f7931e;
}
.header-right {
margin-left: auto;
font-size: 18px;
display: flex;
gap: 16px;
}
.header-right span {
cursor: pointer;
}
.username-show {
color: #2ba245;
font-weight: bold;
}
/* ========== 主体左右分栏 ========== */
.main-body {
flex: 1;
display: flex;
overflow: hidden;
}
.main-content {
flex: 1;
padding: 16px;
overflow-y: auto;
}
.splitter {
width: 8px;
background: #***;
border-left: 1px solid #888;
border-right: 1px solid #888;
cursor: pointer;
flex-shrink: 0;
}
.splitter:hover {
background: #bbb;
}
.sidebar {
width: 300px;
padding: 16px;
overflow-y: auto;
flex-shrink: 0;
}
.sidebar-hide {
display: none;
}
.sidebar-title {
color: #f7931e;
text-align: center;
font-size: 20px;
font-weight: bold;
margin-bottom: 16px;
}
/* ========== 聊天消息 ========== */
.msg-item {
margin-bottom: 12px;
line-height: 1.5;
}
.msg-name {
color: #2ba245;
font-weight: bold;
}
.msg-like {
color: #666;
font-size: 13px;
margin-left: 8px;
cursor: pointer;
}
.msg-like:hover {
color:#f7931e;
}
.msg-time {
color: #999;
font-size: 12px;
margin-left: 6px;
}
/* ========== 帖子卡片 ========== */
.post-card {
border: 1px solid #777;
border-radius: 10px;
padding: 16px;
background: #fafafa;
cursor: pointer;
margin-bottom:14px;
}
.post-card:hover{
background:#f0f0f0;
}
.post-header {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 10px;
}
.post-avatar {
width: 28px;
height: 28px;
border-radius: 50%;
background: #ccc;
border: 1px solid #666;
}
.post-author {
font-weight: bold;
font-size: 17px;
}
.post-date {
color: #666;
font-size: 14px;
}
.post-title {
text-align: center;
font-size: 26px;
margin: 12px 0 20px;
}
.post-content {
line-height: 1.8;
font-size: 16px;
color: #333;
}
/* ========== 底部输入栏 ========== */
.input-bar {
height: 56px;
border-top: 1px solid #888;
display: flex;
align-items: center;
padding: 0 12px;
gap: 10px;
flex-shrink: 0;
}
#msgInput {
flex: 1;
height: 36px;
border: 1px solid #888;
border-radius: 6px;
padding: 0 12px;
font-size: 15px;
outline: none;
}
.send-btn {
width: 60px;
height: 36px;
border: none;
border-radius: 6px;
background: #73bfff;
color: #fff;
font-size: 18px;
cursor: pointer;
}
/* ========== 登录注册弹窗 ========== */
.modal-mask {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0,0,0,0.4);
display: none;
justify-content: center;
align-items: center;
z-index: 999;
}
.modal-show {
display: flex;
}
.modal-box {
width: 380px;
background: #f0f0f0;
border: 2px solid #555;
border-radius: 12px;
overflow: hidden;
}
.modal-header {
display: flex;
border-bottom: 1px solid #888;
position: relative;
}
.modal-tab {
flex: 1;
text-align: center;
line-height: 48px;
font-size: 20px;
cursor: pointer;
}
.modal-tab.active {
color: #f7931e;
border-bottom: 2px solid #f7931e;
font-weight: bold;
}
.modal-close {
position: absolute;
right: 12px;
top: 10px;
font-size: 22px;
cursor: pointer;
color: #555;
}
.modal-body {
padding: 30px 24px;
}
.form-item {
margin-bottom: 24px;
}
.form-item input {
width: 100%;
height: 42px;
border: 1px solid #888;
border-radius: 8px;
padding: 0 14px;
font-size: 16px;
outline: none;
background: #fafafa;
}
.submit-btn {
width: 140px;
height: 46px;
display: block;
margin: 10px auto 0;
background: #f7931e;
color: #fff;
border: 1px solid #555;
border-radius: 10px;
font-size: 18px;
cursor: pointer;
}
.modal-footer {
text-align: center;
color: #333;
padding: 12px;
font-size: 14px;
}
.form-panel {
display: none;
}
.form-panel.active {
display: block;
}
/* ==========帖子详情弹窗 ========== */
.post-detail-mask{
position:fixed;
top:0;left:0;
width:100%;height:100%;
background:rgba(0,0,0,0.4);
z-index:1000;
display:none;
justify-content:center;
align-items:center;
}
.post-detail-mask.show{
display:flex;
}
.post-detail-box{
width:600px;
max-height:80vh;
background:#fff;
border-radius:12px;
border:2px solid #444;
padding:24px;
overflow-y:auto;
}
.post-detail-close{
text-align:right;
font-size:24px;
cursor:pointer;
color:#555;
}
/* ========== T2发帖弹窗 ========== */
.newpost-mask{
position:fixed;
top:0;left:0;
width:100%;height:100%;
background:rgba(0,0,0,0.4);
z-index:1010;
display:none;
justify-content:center;
align-items:center;
}
.newpost-mask.show{
display:flex;
}
.newpost-box{
width:520px;
background:#fff;
border:2px solid #444;
border-radius:12px;
padding:20px;
}
.newpost-close{
text-align:right;
font-size:24px;
cursor:pointer;
color:#555;
}
.newpost-title-input{
width:100%;
height:42px;
font-size:18px;
padding:0 10px;
margin:10px 0;
}
.newpost-textarea{
width:100%;
height:180px;
font-size:16px;
padding:10px;
resize:none;
}
.newpost-submit{
margin-top:12px;
width:120px;
height:42px;
background:#f7931e;
color:white;
border:none;
border-radius:8px;
font-size:17px;
cursor:pointer;
}
</style>
</head>
<body>
<div class="app-container">
<!-- 顶部导航 -->
<div class="header">
<div class="avatar"></div>
<div class="tabs">
<span class="tab-btn active" data-page="chat">聊天</span>
<span class="tab-btn" data-page="tieba">贴吧</span>
</div>
<div class="header-right">
<span id="newPostBtn">发表新帖</span>
<span id="loginBtn">登录</span>
<span id="registerBtn">注册</span>
<span class="username-show" id="usernameShow" style="display:none;"></span>
</div>
</div>
<!-- 主体区域 -->
<div class="main-body">
<!-- 左侧主内容 -->
<div class="main-content" id="mainContent">
<!-- 聊天页面内容 -->
<div class="page-chat" id="pageChat">
</div>
<!-- 贴吧页面内容 -->
<div class="page-tieba" id="pageTieba" style="display:none;">
</div>
</div>
<!-- 分割条 侧边栏开关 -->
<div class="splitter" id="splitter" title="点击切换侧边栏"></div>
<!-- 右侧边栏 -->
<div class="sidebar" id="sidebar">
<!-- 聊天页:显示精华帖 -->
<div class="sidebar-chat" id="sidebarChat">
<div class="sidebar-title">最新精华帖</div>
<div id="sidebarPostList"></div>
</div>
<!-- 贴吧页:显示聊天消息 -->
<div class="sidebar-tieba" id="sidebarTieba" style="display:none;">
<div class="sidebar-title">实时聊天</div>
<div id="sidebarChatList"></div>
</div>
</div>
</div>
<!-- 底部输入栏 -->
<div class="input-bar">
<input type="text" id="msgInput" placeholder="请输入文本">
<button class="send-btn" id="sendBtn">➤</button>
</div>
</div>
<!-- 登录注册弹窗 -->
<div class="modal-mask" id="modalMask">
<div class="modal-box">
<div class="modal-header">
<div class="modal-tab active" data-tab="login">登录</div>
<div class="modal-tab" data-tab="register">注册</div>
<div class="modal-close" id="modalClose">×</div>
</div>
<div class="modal-body">
<!-- 登录表单 -->
<div class="form-panel form-login active">
<div class="form-item">
<input type="text" id="loginUser" placeholder="用户名">
</div>
<div class="form-item">
<input type="password" id="loginPwd" placeholder="密码">
</div>
<button class="submit-btn" id="doLogin">登录</button>
</div>
<!-- 注册表单 -->
<div class="form-panel form-register">
<div class="form-item">
<input type="text" id="regUser" placeholder="用户名">
</div>
<div class="form-item">
<input type="password" id="regPwd" placeholder="密码">
</div>
<button class="submit-btn" id="doRegister">注册</button>
</div>
</div>
<div class="modal-footer">
有问题请联系站长:xxx_eer
</div>
</div>
</div>
<!--帖子详情弹窗 -->
<div class="post-detail-mask" id="postDetailMask">
<div class="post-detail-box">
<div class="post-detail-close" id="postDetailClose">×</div>
<div id="postDetailContent"></div>
</div>
</div>
<!-- T2发帖弹窗 -->
<div class="newpost-mask" id="newPostMask">
<div class="newpost-box">
<div class="newpost-close" id="newPostClose">×</div>
<input class="newpost-title-input" id="postTitle" placeholder="帖子标题">
<textarea class="newpost-textarea" id="postContent" placeholder="帖子内容"></textarea>
<br>
<button class="newpost-submit" id="doNewPost">发布帖子</button>
</div>
</div>
<script>
// ====================== 全局数据 ======================
let currentUser = null; // null代表未登录
let messageList = [];
const postList = [
{
username:"xxx_eer",
time:"2026/1/30",
title:"入站必读",
content:"欢迎来到简易贴吧!\n请文明发言,禁止发布违规内容。\n原型版本仅本地演示,刷新消息丢失。"
},
{
username:"admin",
time:"2026/2/10",
title:"原型版本说明",
content:"本项目为前端原型。\n没有后端服务器,账号保存在浏览器localStorage。\n多人联机需要开发后端服务。"
}
];
const tabBtns = document.querySelectorAll('.tab-btn');
const pageChat = document.getElementById('pageChat');
const pageTieba = document.getElementById('pageTieba');
const sidebarChat = document.getElementById('sidebarChat');
const sidebarTieba = document.getElementById('sidebarTieba');
const sidebarPostList = document.getElementById('sidebarPostList');
const sidebarChatList = document.getElementById('sidebarChatList');
// 渲染帖子列表
function renderPostCard(post){
return `
<div class="post-card" data-index="${postList.indexOf(post)}">
<div class="post-header">
<div class="post-avatar"></div>
<span class="post-author">${post.username}</span>
<span class="post-date">${post.time}</span>
</div>
<div class="post-title">${post.title}</div>
<div class="post-content">${post.content.replace(/\n/g,"<br>")}</div>
</div>`;
}
function refreshAllPost(){
let htmlAll = "";
postList.forEach(p=> htmlAll += renderPostCard(p));
pageTieba.innerHTML = htmlAll;
let htmlSide = "";
postList.forEach(p=> htmlSide += renderPostCard(p));
sidebarPostList.innerHTML = htmlSide;
// 帖子卡片点击打开详情弹窗
document.querySelectorAll(".post-card").forEach(card=>{
card.onclick = function(){
const idx = Number(this.dataset.index);
const p = postList[idx];
document.getElementById("postDetailContent").innerHTML = `
<div class="post-header">
<div class="post-avatar"></div>
<span class="post-author">${p.username}</span>
<span class="post-date">${p.time}</span>
</div>
<div class="post-title">${p.title}</div>
<div class="post-content">${p.content.replace(/\n/g,"<br>")}</div>
`;
document.getElementById("postDetailMask").classList.add("show");
}
})
}
//渲染消息
function renderOneMessage(msgObj){
return `
<div class="msg-item" data-msgid="${msgObj.id}">
<span class="msg-name">${msgObj.username}</span>
<span>: ${msgObj.content}</span>
<span class="msg-like" data-msgid="${msgObj.id}">👍: ${msgObj.like}</span>
<span class="msg-time">${msgObj.time}</span>
</div>`
}
function refreshMessageUI(){
let chatHtml = "";
messageList.forEach(m=> chatHtml += renderOneMessage(m));
pageChat.innerHTML = chatHtml;
sidebarChatList.innerHTML = chatHtml;
//点赞点击事件
document.querySelectorAll(".msg-like").forEach(el=>{
el.onclick = function(e){
e.stopPropagation();
const mid = Number(this.dataset.msgid);
const targetMsg = messageList.find(x=>x.id===mid);
if(targetMsg){
targetMsg.like +=1;
refreshMessageUI();
}
}
})
pageChat.scrollTop = pageChat.scrollHeight;
}
// ========== 页面切换:聊天 / 贴吧 ==========
tabBtns.forEach(btn => {
btn.addEventListener('click', () => {
tabBtns.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const page = btn.dataset.page;
if(page === 'chat'){
pageChat.style.display = 'block';
pageTieba.style.display = 'none';
sidebarChat.style.display = 'block';
sidebarTieba.style.display = 'none';
}else{
pageChat.style.display = 'none';
pageTieba.style.display = 'block';
sidebarChat.style.display = 'none';
sidebarTieba.style.display = 'block';
}
});
});
// ========== 侧边栏开关 ==========
const splitter = document.getElementById('splitter');
const sidebar = document.getElementById('sidebar');
splitter.addEventListener('click', () => {
sidebar.classList.toggle('sidebar-hide');
});
// ========== 发送消息 未登录拦截 ==========
const msgInput = document.getElementById('msgInput');
const sendBtn = document.getElementById('sendBtn');
let msgIdCounter = 1;
function sendMessage(){
if(currentUser === null){
alert("请先登录后再发送消息!");
return;
}
const text = msgInput.value.trim();
if(!text) return;
const now = new Date();
const timeStr = now.getFullYear()+'/'+(now.getMonth()+1)+'/'+now.getDate();
const newMsg = {
id: msgIdCounter++,
username: currentUser,
content:text,
time:timeStr,
like:0
};
messageList.push(newMsg);
refreshMessageUI();
msgInput.value = '';
}
sendBtn.addEventListener('click', sendMessage);
msgInput.addEventListener('keydown', e => {
if(e.key === 'Enter') sendMessage();
});
// ========== 登录注册弹窗 ==========
const modalMask = document.getElementById('modalMask');
const loginBtn = document.getElementById('loginBtn');
const registerBtn = document.getElementById('registerBtn');
const modalClose = document.getElementById('modalClose');
const modalTabs = document.querySelectorAll('.modal-tab');
const formPanels = document.querySelectorAll('.form-panel');
function openModal(tab){
modalMask.classList.add('modal-show');
modalTabs.forEach(t => t.classList.remove('active'));
formPanels.forEach(p => p.classList.remove('active'));
if(tab === 'login'){
modalTabs[0].classList.add('active');
formPanels[0].classList.add('active');
}else{
modalTabs[1].classList.add('active');
formPanels[1].classList.add('active');
}
}
loginBtn.addEventListener('click', () => openModal('login'));
registerBtn.addEventListener('click', () => openModal('register'));
modalClose.addEventListener('click', () => modalMask.classList.remove('modal-show'));
modalTabs.forEach(tab => {
tab.addEventListener('click', () => {
const type = tab.dataset.tab;
openModal(type);
});
});
// ========== 注册 & 登录逻辑 ==========
const doRegister = document.getElementById('doRegister');
const doLogin = document.getElementById('doLogin');
const usernameShow = document.getElementById('usernameShow');
if(!localStorage.getItem('chat_users')){
localStorage.setItem('chat_users', JSON.stringify([]));
}
doRegister.addEventListener('click', () => {
const user = document.getElementById('regUser').value.trim();
const pwd = document.getElementById('regPwd').value.trim();
if(!user || !pwd){
alert('用户名和密码不能为空');
return;
}
const users = JSON.parse(localStorage.getItem('chat_users'));
if(users.find(u => u.username === user)){
alert('用户名已存在');
return;
}
users.push({username: user, password: pwd});
localStorage.setItem('chat_users', JSON.stringify(users));
alert('注册成功,请登录');
openModal('login');
});
doLogin.addEventListener('click', () => {
const user = document.getElementById('loginUser').value.trim();
const pwd = document.getElementById('loginPwd').value.trim();
const users = JSON.parse(localStorage.getItem('chat_users'));
const target = users.find(u => u.username === user && u.password === pwd);
if(target){
currentUser = user;
usernameShow.textContent = user;
usernameShow.style.display = 'inline';
loginBtn.style.display = 'none';
registerBtn.style.display = 'none';
modalMask.classList.remove('modal-show');
}else{
alert('用户名或密码错误');
}
});
//帖子详情弹窗关闭
document.getElementById("postDetailClose").onclick = function(){
document.getElementById("postDetailMask").classList.remove("show");
}
// ========= T2 发帖功能 =========
const newPostBtn = document.getElementById("newPostBtn");
const newPostMask = document.getElementById("newPostMask");
const newPostClose = document.getElementById("newPostClose");
const doNewPost = document.getElementById("doNewPost");
const postTitle = document.getElementById("postTitle");
const postContent = document.getElementById("postContent");
newPostBtn.onclick = function(){
if(currentUser === null){
alert("请先登录,才能发帖!");
return;
}
newPostMask.classList.add("show");
}
newPostClose.onclick = function(){
newPostMask.classList.remove("show");
postTitle.value = "";
postContent.value = "";
}
doNewPost.onclick = function(){
const t = postTitle.value.trim();
const c = postContent.value.trim();
if(!t){
alert("标题不能为空");
return;
}
if(!c){
alert("帖子内容不能为空");
return;
}
const now = new Date();
const timeStr = now.getFullYear()+'/'+(now.getMonth()+1)+'/'+now.getDate();
const newPostObj = {
username: currentUser,
time: timeStr,
title: t,
content: c
};
postList.unshift(newPostObj);
refreshAllPost();
newPostMask.classList.remove("show");
postTitle.value = "";
postContent.value = "";
alert("发帖成功!");
}
//初始化页面
refreshAllPost();
</script>
</body>
</html>
这里空空如也


















有帮助,赞一个