AI聊天对话界面的HTML代码。
AI聊天对话界面的HTML代码。它实现了一个功能完整的聊天机器人,您可以直接在浏览器中运行,无需任何外部文件。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>AI 智能助手 | 对话聊天界面</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: linear-gradient(145deg, #e0eafc 0%, #cfdef3 100%);
font-family: 'Segoe UI', 'Inter', system-ui, -apple-system, 'Roboto', 'Helvetica Neue', sans-serif;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
}
/* 聊天容器卡片 */
.chat-container {
width: 100%;
max-width: 800px;
height: 90vh;
max-height: 85vh;
background: rgba(255, 255, 255, 0.96);
border-radius: 32px;
box-shadow: 0 25px 45px -12px rgba(0, 0, 0, 0.35), 0 2px 8px rgba(0, 0, 0, 0.05);
backdrop-filter: blur(0px);
display: flex;
flex-direction: column;
overflow: hidden;
transition: all 0.2s ease;
}
/* 头部 */
.chat-header {
background: #1e2b3c;
color: white;
padding: 20px 24px;
display: flex;
align-items: center;
gap: 14px;
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}
.ai-avatar {
background: #2c7da0;
width: 46px;
height: 46px;
border-radius: 28px;
display: flex;
align-items: center;
justify-content: center;
font-size: 26px;
font-weight: 500;
box-shadow: 0 4px 10px rgba(0,0,0,0.2);
}
.header-text {
flex: 1;
}
.header-text h1 {
font-size: 1.45rem;
font-weight: 600;
letter-spacing: -0.3px;
}
.header-text p {
font-size: 0.8rem;
opacity: 0.8;
margin-top: 4px;
}
.status-badge {
background: #2c7da0;
padding: 6px 12px;
border-radius: 40px;
font-size: 0.7rem;
font-weight: 500;
background: #1f5068;
}
/* 消息区域 */
.messages-area {
flex: 1;
overflow-y: auto;
padding: 20px 18px;
display: flex;
flex-direction: column;
gap: 18px;
background: #f9fafc;
scroll-behavior: smooth;
}
/* 自定义滚动条 */
.messages-area::-webkit-scrollbar {
width: 5px;
}
.messages-area::-webkit-scrollbar-track {
background: #e9ecef;
border-radius: 4px;
}
.messages-area::-webkit-scrollbar-thumb {
background: #b9c4d0;
border-radius: 4px;
}
/* 消息气泡 */
.message {
display: flex;
gap: 12px;
max-width: 85%;
animation: fadeSlideUp 0.25s ease-out;
}
.message.user {
align-self: flex-end;
flex-direction: row-reverse;
}
.message.ai {
align-self: flex-start;
}
.avatar-icon {
width: 36px;
height: 36px;
background: #eef2f7;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
flex-shrink: 0;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.user .avatar-icon {
background: #1e2b3c;
color: white;
}
.ai .avatar-icon {
background: #2c7da0;
color: white;
}
.bubble {
background: white;
padding: 12px 18px;
border-radius: 24px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
font-size: 0.95rem;
line-height: 1.45;
color: #1e2b3c;
word-break: break-word;
white-space: pre-wrap;
}
.user .bubble {
background: #1e2b3c;
color: white;
border-bottom-right-radius: 6px;
}
.ai .bubble {
background: white;
border-bottom-left-radius: 6px;
border: 1px solid #e2e8f0;
}
/* 打字指示器 */
.typing-indicator {
display: flex;
align-items: center;
gap: 6px;
padding: 10px 16px;
background: white;
border-radius: 24px;
width: fit-content;
border: 1px solid #e2e8f0;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.typing-indicator span {
width: 8px;
height: 8px;
background: #90a4bc;
border-radius: 50%;
display: inline-block;
animation: bounce 1.4s infinite ease-in-out both;
}
.typing-indicator span:nth-child(1) { animation-delay: -0.32s; }
.typing-indicator span:nth-child(2) { animation-delay: -0.16s; }
@keyframes bounce {
0%, 80%, 100% { transform: scale(0.6); opacity: 0.5; }
40% { transform: scale(1); opacity: 1; }
}
/* 输入区域 */
.input-area {
background: white;
padding: 14px 20px 20px;
border-top: 1px solid #eef2f8;
display: flex;
gap: 12px;
align-items: flex-end;
}
.input-wrapper {
flex: 1;
background: #f1f5f9;
border-radius: 32px;
padding: 8px 18px;
display: flex;
align-items: center;
gap: 10px;
border: 1px solid #e2edf2;
transition: all 0.2s;
}
.input-wrapper:focus-within {
border-color: #2c7da0;
background: white;
box-shadow: 0 0 0 2px rgba(44,125,160,0.2);
}
#messageInput {
flex: 1;
border: none;
background: transparent;
padding: 10px 0;
font-size: 0.95rem;
outline: none;
resize: none;
font-family: inherit;
max-height: 120px;
color: #1e2b3c;
}
#messageInput::placeholder {
color: #8ca3b9;
font-weight: 400;
}
.send-btn {
background: #2c7da0;
border: none;
width: 42px;
height: 42px;
border-radius: 42px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: 0.2s;
color: white;
font-size: 20px;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
.send-btn:hover {
background: #1f5e7a;
transform: scale(0.96);
}
.send-btn:active {
transform: scale(0.92);
}
/* 清空按钮 优雅小按钮 */
.action-bar {
display: flex;
justify-content: flex-end;
padding: 6px 20px 0;
background: #f9fafc;
}
.clear-btn {
background: none;
border: none;
font-size: 0.7rem;
color: #7f8fa4;
cursor: pointer;
padding: 6px 12px;
border-radius: 40px;
transition: 0.2s;
display: flex;
align-items: center;
gap: 6px;
}
.clear-btn:hover {
background: #eef2fa;
color: #1e2b3c;
}
/* 入场动画 */
@keyframes fadeSlideUp {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 响应式微调 */
@media (max-width: 550px) {
.message {
max-width: 92%;
}
.chat-container {
height: 92vh;
border-radius: 26px;
}
.bubble {
font-size: 0.88rem;
padding: 10px 14px;
}
}
</style>
</head>
<body>
<div class="chat-container">
<div class="chat-header">
<div class="ai-avatar">✨</div>
<div class="header-text">
<h1>AI 智慧引擎</h1>
<p>随时为你解答 · 灵感伙伴</p>
</div>
<div class="status-badge" id="statusBadge">在线</div>
</div>
<div class="action-bar">
<button class="clear-btn" id="clearChatBtn" aria-label="清空对话">🗑️ 清除记录</button>
</div>
<div class="messages-area" id="messagesArea">
<!-- 消息动态渲染位置 -->
<div class="message ai">
<div class="avatar-icon">🤖</div>
<div class="bubble">
嗨!我是你的AI助手 🌟<br> 可以问我任何问题,编程、写作、生活建议,或是随便聊聊天~
</div>
</div>
</div>
<div class="input-area">
<div class="input-wrapper">
<textarea id="messageInput" placeholder="输入消息..." rows="1" style="overflow: hidden;"></textarea>
</div>
<button class="send-btn" id="sendBtn">➤</button>
</div>
</div>
<script>
// ---------- DOM 元素 ----------
const messagesArea = document.getElementById('messagesArea');
const messageInput = document.getElementById('messageInput');
const sendBtn = document.getElementById('sendBtn');
const clearBtn = document.getElementById('clearChatBtn');
const statusBadge = document.getElementById('statusBadge');
// ---------- 状态管理 ----------
let isWaitingForAI = false; // 是否正在等待AI回复(防止重复发送)
let currentTypingElement = null; // 临时占位指示器元素
// 本地存储Key (用于保留对话历史,提升体验)
const STORAGE_KEY = 'ai_chat_messages';
// 初始加载消息历史 (最多保留最近50条,并且需要数据结构符合渲染格式)
let conversationHistory = []; // 存储 { role: 'user' 或 'assistant', content: string }
// 辅助:从 localstorage 读取并初始化
function loadMessagesFromStorage() {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored) {
try {
const arr = JSON.parse(stored);
if (Array.isArray(arr) && arr.length) {
conversationHistory = arr.slice(-50); // 限制长度,避免过大
// 重新渲染界面
renderMessagesFromHistory();
return;
}
} catch(e) { console.warn(e); }
}
// 默认欢迎消息 (如果没有储存)
if (conversationHistory.length === 0) {
conversationHistory = [
{ role: 'assistant', content: '嗨!我是你的AI助手 🌟\n可以问我任何问题,编程、写作、生活建议,或是随便聊聊天~' }
];
saveToLocalStorage();
renderMessagesFromHistory();
} else {
renderMessagesFromHistory();
}
}
// 保存到 localStorage
function saveToLocalStorage() {
// 只保留最后100条,避免溢出
const toStore = conversationHistory.slice(-100);
localStorage.setItem(STORAGE_KEY, JSON.stringify(toStore));
}
// 完全根据 conversationHistory 重新绘制消息区域 (保留滚动到底部)
function renderMessagesFromHistory() {
if (!messagesArea) return;
// 清空区域,但是保留消息容器结构
messagesArea.innerHTML = '';
for (let msg of conversationHistory) {
const messageDiv = createMessageElement(msg.role, msg.content);
messagesArea.appendChild(messageDiv);
}
scrollToBottom();
}
// 创建单条消息DOM元素 (纯展示)
function createMessageElement(role, content) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${role === 'user' ? 'user' : 'ai'}`;
const avatarDiv = document.createElement('div');
avatarDiv.className = 'avatar-icon';
avatarDiv.innerText = role === 'user' ? '👤' : '🤖';
const bubbleDiv = document.createElement('div');
bubbleDiv.className = 'bubble';
// 支持换行文本保留格式
bubbleDiv.innerText = content;
// 简单支持链接识别? 暂不过多高级渲染但保留文本可读性
messageDiv.appendChild(avatarDiv);
messageDiv.appendChild(bubbleDiv);
return messageDiv;
}
// 滚动到底部 (平滑)
function scrollToBottom() {
if (messagesArea) {
messagesArea.scrollTo({
top: messagesArea.scrollHeight,
behavior: 'smooth'
});
}
}
// 显示 "AI正在输入..." 的指示器 (在消息区最后)
function showTypingIndicator() {
if (currentTypingElement) return; // 已存在则不重复添加
const typingWrapper = document.createElement('div');
typingWrapper.className = 'message ai';
typingWrapper.id = 'typingIndicatorWrapper';
const avatarIcon = document.createElement('div');
avatarIcon.className = 'avatar-icon';
avatarIcon.innerText = '🤖';
const indicatorDiv = document.createElement('div');
indicatorDiv.className = 'typing-indicator';
indicatorDiv.innerHTML = '<span></span><span></span><span></span>';
typingWrapper.appendChild(avatarIcon);
typingWrapper.appendChild(indicatorDiv);
messagesArea.appendChild(typingWrapper);
currentTypingElement = typingWrapper;
scrollToBottom();
}
function removeTypingIndicator() {
if (currentTypingElement && currentTypingElement.parentNode) {
currentTypingElement.remove();
currentTypingElement = null;
}
}
// 核心:添加新消息到界面和历史,并持久化
function addMessageToChat(role, content, skipStorage = false) {
// 添加至历史数组
if (!skipStorage) {
conversationHistory.push({ role, content });
saveToLocalStorage();
}
// 渲染该条消息(直接追加,避免重绘全量,提升性能)
const messageElem = createMessageElement(role, content);
messagesArea.appendChild(messageElem);
scrollToBottom();
}
// 模拟AI 回复 (聪明响应 + 简单上下文参考)
// 这里为了展现真实对话感,AI会依据对话历史和当前用户消息智能生成不同风格的回复
async function generateAIResponse(userMessage) {
// 模拟网络延迟 400~1500ms,让体验更自然
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(600 + Math.random() * 700);
// 小技巧: 让AI具备基本的意图识别和有趣回答,增强实用性。
const lowerMsg = userMessage.toLowerCase().trim();
// 1. 问候类
if (lowerMsg.match(/^(你好|嗨|hi|hello|在吗|您好)/)) {
return "你好呀!😊 有什么我可以帮到你的吗?随时分享你的想法~";
}
// 2. 提问时间/日期
if (lowerMsg.includes('时间') || lowerMsg.includes('几点了') || lowerMsg.includes('日期') || lowerMsg.includes('今天')) {
const now = new Date();
const dateStr = `${now.getFullYear()}年${now.getMonth()+1}月${now.getDate()}日`;
const timeStr = `${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}`;
return `📅 现在是 ${dateStr} ${timeStr},记得劳逸结合哦!`;
}
// 3. 笑话 / 轻松时刻
if (lowerMsg.includes('笑话') || lowerMsg.includes('幽默') || lowerMsg.includes('讲个笑话')) {
const jokes = [
"为什么程序员总是分不清万圣节和圣诞节?因为 Oct 31 = Dec 25!😂",
"AI 和人类有什么区别?AI 不会忘记保存文件,但我猜你会~",
"“为什么电脑总是很冷?” “因为它有Windows(窗户)开着呢!”",
"数学老师说:『统计表明,80%的人会因为笑话冷而沉默』。我:『那剩下的20%呢?』老师:『他们在想别的笑话。』🤣"
];
return jokes[Math.floor(Math.random() * jokes.length)];
}
// 4. 编程/技术帮助
if (lowerMsg.includes('代码') || lowerMsg.includes('python') || lowerMsg.includes('javascript') || lowerMsg.includes('html') || lowerMsg.includes('怎么实现')) {
return "💻 关于代码问题,可以具体描述你的需求~ 我支持给出示例、解释逻辑或调试思路。比如你想实现一个排序算法?或是前端的布局小技巧?随时细化,我为你解答。";
}
// 5. 关于AI自身
if (lowerMsg.includes('你是谁') || lowerMsg.includes('你叫什么') || lowerMsg.includes('你的功能')) {
return "我是智能对话助手,内置轻量知识库,可以陪你聊天、解决问题、构思创意。纯前端模拟但反应够快,并且记忆当前对话上下文 🌟";
}
// 6. 情感/鼓励类
if (lowerMsg.includes('压力') || lowerMsg.includes('好累') || lowerMsg.includes('焦虑') || lowerMsg.includes('加油')) {
return "你已经很棒了!每一个努力的瞬间都值得肯定 ✨ 适当放松,做些喜欢的事,我会一直在这儿支持你。";
}
// 7. 如果用户消息较长或者问意见
if (userMessage.length > 20 && (lowerMsg.includes('怎么') || lowerMsg.includes('建议') || lowerMsg.includes('推荐'))) {
return "收到你的详细描述!根据你的需求,我的建议是:先理清楚核心目标,拆解成小任务逐步完成。如果需要更具体的方案,可以再告诉我更多背景信息,一起头脑风暴~";
}
// 8. 默认智能回话: 引用上下文情感
const contextReferences = [
"有趣的话题!🤔 让我想想…… 其实我觉得可以换个角度思考,你觉得呢?",
"收到!✨ 你说的很有启发性,我正在学习。还有更多细节想讨论的吗?",
"这个问题很有意思!我相信持续探索会让你发现更多可能。需要我给出例子吗?",
"明白啦。根据对话历史来看,我们继续深入的话,或许可以试试看不同的方法。"
];
// 简单使用随机 + 带点礼貌
return contextReferences[Math.floor(Math.random() * contextReferences.length)] + " 你的消息我已记住:「" + (userMessage.length > 32 ? userMessage.slice(0,32)+"…" : userMessage) + "」";
}
// 发送消息主流程
async function sendUserMessage() {
if (isWaitingForAI) return;
const rawMessage = messageInput.value.trim();
if (rawMessage === "") return;
// 清空输入框 & 重置高度
messageInput.value = "";
messageInput.style.height = "auto";
// 1. 添加用户消息到界面及历史
addMessageToChat('user', rawMessage);
// 2. 设置等待标志,避免并发
isWaitingForAI = true;
statusBadge.innerText = "思考中...";
statusBadge.style.background = "#8b5f2e";
// 3. 显示正在输入指示器 (打字效果)
showTypingIndicator();
try {
// 调用模拟AI响应(可以基于整个conversationHistory,但这里传给generate函数当前用户消息+智能判断)
const aiReply = await generateAIResponse(rawMessage);
// 移除打字指示器
removeTypingIndicator();
// 添加AI回复到界面和历史
addMessageToChat('assistant', aiReply);
} catch (error) {
console.error("AI回复出错", error);
removeTypingIndicator();
addMessageToChat('assistant', "抱歉,我遇到了一点技术小故障,请稍后再试~🧐");
} finally {
isWaitingForAI = false;
statusBadge.innerText = "在线";
statusBadge.style.background = "#1f5068";
// 确保输入框焦点
messageInput.focus();
}
}
// 清空对话(同时清除存储和历史,重置初始欢迎语)
function clearConversation() {
if (isWaitingForAI) return;
// 重置历史数组
conversationHistory = [
{ role: 'assistant', content: '对话已重置✨ 我是你的AI助手,有什么新问题都可以问我~' }
];
saveToLocalStorage();
// 重绘界面
renderMessagesFromHistory();
// 移除任何残留打字指示器
removeTypingIndicator();
isWaitingForAI = false;
statusBadge.innerText = "在线";
statusBadge.style.background = "#1f5068";
// 让输入框可交互
messageInput.focus();
}
// 事件绑定 & 辅助:textarea 自适应高度
function autoResizeTextarea() {
messageInput.style.height = 'auto';
messageInput.style.height = Math.min(messageInput.scrollHeight, 120) + 'px';
}
// 键盘监听 (回车发送,但是Shift+Enter换行)
function onInputKeydown(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendUserMessage();
}
}
// 初始化事件和加载存储
function init() {
loadMessagesFromStorage(); // 加载历史并渲染
sendBtn.addEventListener('click', sendUserMessage);
clearBtn.addEventListener('click', clearConversation);
messageInput.addEventListener('input', autoResizeTextarea);
messageInput.addEventListener('keydown', onInputKeydown);
messageInput.focus();
// 初次加载滚动到底部
scrollToBottom();
// 防止多次快速点击清除导致状态异常
}
// 页面启动
init();
</script>
</body>
</html>
fffffffffffffffff
test red font.

浙公网安备 33010602011771号