Tailwind css实战,基于Kooboo构建AI对话框页面(二)

基于上篇内容,添加交互逻辑,实现一个伪聊天功能的对话框效果: 

Tailwind css实战,基于Kooboo构建AI对话框页面(一)-CSDN博客


在前期文章中,我们完成了 AI 对话框的静态页面搭建。本文将聚焦交互逻辑开发,通过原生 JavaScript 实现消息发送 / 接收动态渲染“正在输入” 动画反馈关键词触发的智能回复,最终实现一个具备对话能力的交互界面。以下是核心功能的代码实现与逻辑解析:

一、技术栈

1. 技术栈说明

  • Kooboo:快速构建对话界面的静态结构(如消息容器、输入框、按钮的布局)。通过拖拽组件和样式配置(直接应用 Tailwind 类名),生成基础 HTML 框架,无需手动编写重复代码。
  • Tailwind CSS:通过类名快速实现对话气泡样式(如bg-blue-600用户消息、bg-whiteAI 回复)
  • 原生 JavaScript:通过监听用户操作,动态渲染消息,与 Kooboo 生成的静态 DOM 无缝协作,确保交互功能的灵活性

二、核心文件结构

1. 初始化与 DOM 元素获取

document.addEventListener('DOMContentLoaded', function() {const messageContainer = document.getElementById('messageContainer');const messageInput = document.getElementById('messageInput');const sendButton = document.getElementById('sendButton');
});
  • 事件监听:页面 DOM 加载完成后执行初始化
  • 元素引用:获取消息容器、输入框和发送按钮的 DOM 节点

2. 时间格式化函数

// 获取当前时间(格式:HH:MM AM/PM)
function getCurrentTime() {const now = new Date();let hours = now.getHours();let minutes = now.getMinutes();const ampm = hours >= 12 ? 'PM' : 'AM';hours = hours % 12;hours = hours ? hours : 12; // 0点转为12点minutes = minutes < 10 ? '0'+minutes : minutes;return `${hours}:${minutes} ${ampm}`;
}
  • 时间格式:将 24 小时制转换为 12 小时制(例如:2:30 PM
  • 补零处理:分钟数小于 10 时添加前导零(例如:2:05 PM

3. 消息发送功能

     3.1 获取用户输入并校验

function sendMessage() {const message = messageInput.value.trim();if (message === '') return; // 忽略空消息
  • 去除空格:获取输入框中的内容并去除前后空格。
  • 空消息过滤:如果输入内容为空,直接返回,不执行后续操作,避免发送空消息。

      3.2 生成用户消息的 HTML 结构

// 添加用户消息const userMessageHtml = `<div class="flex items-start space-x-2 justify-end"><div class="max-w-[70%]"><div class="bg-blue-600 text-white p-4 rounded-lg rounded-tr-none shadow-sm"><p>${message}</p><span class="text-xs text-blue-200 mt-1 block">${getCurrentTime()}</span></div></div><div class="w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center"><span class="text-white">我</span></div></div>
  • 外层容器flex items-start space-x-2 justify-end:使用弹性布局,子元素从顶部开始排列,水平间距为 2 单位,用户消息右对齐(justify-end)。
  • 消息内容区域max-w-[70%]:消息内容最大宽度为父容器的 70%,避免消息过宽。
  • 消息气泡bg-blue-600 text-white p-4 rounded-lg rounded-tr-none shadow-sm:蓝色背景,白色文字,内边距 4 单位,圆角(右上角为直角,rounded-tr-none),添加阴影。
  • 消息内容<p>${message}</p>:显示用户输入的消息内容。
  • 时间戳<span class="text-xs text-blue-200 mt-1 block">${getCurrentTime()}</span>:小字体,浅蓝色,距离顶部 1 单位,块级元素,显示当前时间(通过getCurrentTime函数获取)。
  • 用户头像w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center:8x8 单位的圆形,蓝色背景,内部文字 “我” 居中显示。

        3.3 插入用户消息到容器

messageContainer.insertAdjacentHTML('beforeend', userMessageHtml);
  • 将生成的用户消息 HTML 插入到messageContainer的末尾,更新界面显示用户消息。

        3.4 清空输入框并聚焦

messageInput.value = '';
messageInput.focus();
  • 清空输入框内容,准备接收下一条消息,并将焦点保持在输入框,方便用户继续输入。

        3.5 滚动到底部

scrollToBottom();
  • 调用scrollToBottom函数,确保消息容器滚动到最底部,显示最新的用户消息。

4. "正在输入" 动画效果

// 显示加载指示器
const typingIndicator = `<div id="typingIndicator" class="flex items-start space-x-2"><div class="w-8 h-8 rounded-full bg-gray-200 flex items-center justify-center">🤖</div><div class="max-w-[70%]"><div class="bg-white p-4 rounded-lg rounded-tl-none shadow-sm"><div class="flex space-x-1"><div class="w-2 h-2 rounded-full bg-gray-400 animate-pulse"></div><div class="w-2 h-2 rounded-full bg-gray-400 animate-pulse" style="animation-delay: 0.2s"></div><div class="w-2 h-2 rounded-full bg-gray-400 animate-pulse" style="animation-delay: 0.4s"></div></div></div></div></div>
`;
messageContainer.insertAdjacentHTML('beforeend', typingIndicator);
scrollToBottom();
  • 动画实现:使用三个小圆点的脉冲动画(animate-pulse
  • 交错延迟:通过 CSS 动画延迟(0.2s 和 0.4s)创造波浪效果
  • AI 标识:使用🤖图标区分 AI 回复

5. 模拟 AI 回复逻辑

// 模拟AI回复setTimeout(() => {// 移除"正在输入"指示器const typing = document.getElementById('typingIndicator');if (typing) typing.remove();// 根据用户消息生成不同的回复let aiResponse = "";if (message.toLowerCase().includes('python')) {aiResponse = `这是一个简单的Python函数示例:def calculate_sum(a, b):"""计算两个数字的和"""return a + b# 调用函数result = calculate_sum(5, 3)print(f"结果是: {result}") \n这个函数接受两个参数并返回它们的和。`;} else if (message.toLowerCase().includes('hello') || message.toLowerCase().includes('hi')) {aiResponse = "您好!很高兴见到您。有什么我可以帮助您的吗?";} else if (message.includes('你是谁')) {aiResponse = "我是AI小助手,您的智能聊天伙伴!";} else {aiResponse = "感谢您的提问。我正在学习更多知识,以便更好地回答您的问题。";}// 添加AI回复const aiMessageHtml = `<div class="flex items-start space-x-2"><div class="w-8 h-8 rounded-full bg-gray-200 flex items-center justify-center">🤖</div><div class="max-w-[70%]"><div class="bg-white p-4 rounded-lg rounded-tl-none shadow-sm"><pre class="text-sm bg-gray-50 p-3 rounded-md"><code>${aiResponse}</code></pre><span class="text-xs text-gray-500 mt-2 block">${getCurrentTime()}</span></div></div></div>`;messageContainer.insertAdjacentHTML('beforeend', aiMessageHtml);scrollToBottom();}, 1000 + Math.random() * 1000); // 随机延迟1-2秒}
  • 关键词匹配:根据用户输入内容生成不同回复
  • 代码格式化:使用<pre><code>标签保持 Python 代码格式
  • 随机延迟:模拟 AI 思考时间,增强真实感

6. 滚动控制函数

function scrollToBottom() {messageContainer.scrollTop = messageContainer.scrollHeight;
}
  • 自动滚动:确保最新消息始终可见
  • 调用时机:发送消息后、显示 / 隐藏加载指示器后

7. 事件绑定

// 按钮点击触发发送
sendButton.addEventListener('click', sendMessage);// 回车键触发发送
messageInput.addEventListener('keypress', function(e) {if (e.key === 'Enter') {sendMessage();}
});// 页面加载后自动聚焦输入框
messageInput.focus();
  • 双触发机制:支持鼠标点击和键盘回车发送消息
  • 自动聚焦:用户无需手动点击输入框

8. 消息 UI 设计

元素用户消息AI 回复
气泡颜色蓝色 (bg-blue-600)白色 (bg-white)
对齐方式右对齐 (justify-end)左对齐(默认)
头像蓝色圆形 + 文字 "我"灰色圆形 +🤖图标
时间戳浅蓝色小字 (text-blue-200)浅灰色小字 (text-gray-500)
最大宽度70% (max-w-[70%])70% (max-w-[70%])

三、总结

整个交互逻辑的流程就是:当页面加载完成后,通过ID绑定获取输入框、发送按钮和消息容器元素,监听按钮点击和回车事件触发消息发送——用户输入经非空验证后,以右侧蓝色气泡形式显示并附带时间戳,随后展示左侧的"正在输入"动画,经过1-2秒模拟延迟后,根据消息关键词(如Python/问候语/身份询问)动态生成对应回复,以代码块或文本形式在左侧灰色气泡中呈现,整个过程通过DOM操作实时更新界面并保持自动滚动,形成完整的伪实时对话交互闭环。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/84752.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Conda:环境移植及更新1--使用conda-pack

更多内容&#xff1a;XiaoJ的知识星球 目录 一、使用conda-pack1.安装 conda-pack2.移植整个 Anaconda 环境3.移植单个虚拟环境4.验证是否生效 在相同Linux设备上移植Miniconda3&#xff08;Anaconda3同理&#xff09;常用方法有。 使用conda-pack&#xff1a;使用conda-pack工…

树莓派超全系列教程文档--(50)如何查找树莓派的IP地址

如何查找树莓派的IP地址 找到您的Raspberry Pi的IP地址桌面命令行引导输出网络管理器使用mDNS解析 raspberrypi.local检查路由器的设备列表使用 nmap 查找设备使用智能手机应用程序查找设备 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 找到您…

如何优化 MySQL 存储过程的性能?

文章目录 1. 优化 SQL 语句避免全表扫描减少子查询&#xff0c;改用 JOIN避免 SELECT 2. 合理使用索引3. 优化存储过程结构减少循环和临时变量避免重复计算 4. 使用临时表和缓存5. 优化事务处理6. 分析和监控性能7. 优化数据库配置8. 避免用户自定义函数&#xff08;UDF&#…

尚硅谷redis7 47-48 redis事务之理论简介

47 redis事务之理论简介 什么是事务 可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入 能干什么&#xff1f; 一个队列中&#xff0c;一次性、顺序性、排他性的执行一系列操作 redis事务vs数据库事务 …

Nginx 在四大核心场景中的应用实践与优化

一、Nginx 核心应用场景深度解析 1. HTTP 服务器&#xff1a;静态资源的高性能承载者 Nginx 作为 HTTP 服务器时&#xff0c;凭借轻量级架构和高效的事件驱动模型&#xff0c;成为静态资源服务的首选方案。 核心能力与场景 静态文件高效处理&#xff1a;直接响应 HTML、CSS…

亚当·斯密思想精髓的数学建模与形式化表征

亚当斯密思想精髓的数学建模与形式化表征 摘要&#xff1a;本文运用数学建模方法对亚当斯密的经济与伦理思想进行形式化表征。通过分工的规模经济模型和市场均衡条件展现《国富论》中"看不见的手"原理&#xff1b;采用扩展效用函数与合作博弈均衡解释《道德情操论》…

FastDFS集群部署与性能优化实战

目录 一、介绍 二、FastDFS原理 三、FastDFS部署 1.资源清单 2.修改主机名 3.安装libfastcommon&#xff08;tracker01、tracker02、storage1、storage2&#xff09; 4.安装编译FastDFS&#xff08;tracker01、tracker02、storage1、storage2&#xff09; 5.配置tracker…

学习心得(14--16)

模板&#xff1a; 前端的页面单独存在模板当中 jinja2 &#xff1a;模板语法 保持前端页面不变的情况下&#xff0c;返回内容给前端做法&#xff1a; 写一个data&#xff0c;并在return中的render_template中&#xff0c;写上datadata 使用时&#xff0c;要将templa…

stm与51单片机哪个更适合新手学

一句话总结 51单片机&#xff1a;像学骑自行车&#xff0c;简单便宜&#xff0c;但只能在小路上骑。 STM32&#xff1a;像学开汽车&#xff0c;复杂但功能强&#xff0c;能上高速公路&#xff0c;还能拉货载人&#xff08;做复杂项目&#xff09;。 1. 为啥有人说“先学51单片…

Web安全测试-文件上传绕过-DVWA

Web安全测试-文件上传绕过-DVWA 很多网站都有上传资源(图片或者文件)的功能&#xff0c;资源上传后一般会存储在服务器的一个文件夹里面&#xff0c;如果攻击者绕过了上传时候的文件类型验证&#xff0c;传了木马或者其他可执行的代码上去&#xff0c;那服务器就危险了。 我用…

ant-design-vue中的分页组件自定义

ant-design-vue中的分页组件自定义 实现效果 实现代码 需要自己创建一个分页组件的代码然后导入进去。 <template><div style"display: flex; justify-content: space-between; margin-bottom: 10px"><div><a-select v-model:value"pageS…

LabVIEW软件开发过程中如何保证软件的质量?

一、需求与架构设计阶段 明确功能边界与技术指标 在测试系统设计初期&#xff0c;围绕比例阀性能测试核心需求&#xff08;如压力 / 流量信号采集、特性曲线绘制、数据对比分析&#xff09;&#xff0c;定义软件功能模块&#xff08;数据采集、逻辑控制、界面显示&#xff09;&…

Linux 527 重定向 2>1 rsync定时同步(未完)

rsync定时同步 配环境 关闭防火墙、selinux systemctl stop firewalld systemctl disable firewalld setenforce0 vim /etc/SELINUX/config SELINUXdisable515 设置主机名 systemctl set-hostname code systemctl set-hostname backup 配静态ip rsync 需要稳定的路由表和端…

Vue 3.0 中状态管理Vuex 与 Pinia 的区别

在 Vue.js 应用开发中&#xff0c;状态管理是构建复杂应用的关键环节。随着 Vue 3 的普及和 Composition API 的引入&#xff0c;开发者面临着状态管理库的选择问题&#xff1a;是继续使用经典的 Vuex&#xff0c;还是转向新兴的 Pinia&#xff1f;本文将从设计理念、API 设计、…

分布式缓存:三万字详解Redis

文章目录 缓存全景图PreRedis 整体认知框架一、Redis 简介二、核心特性三、性能模型四、持久化详解五、复制与高可用六、集群与分片方案 Redis 核心数据类型概述1. String2. List3. Set4. Sorted Set&#xff08;有序集合&#xff09;5. Hash6. Bitmap7. Geo8. HyperLogLog Red…

React useEffect和useEffectLa

原理把对象以树的形式存档&#xff0c;根据URL进行匹配渲染对应组件 useEffect 和useLayoutEffect区别 useEffect中的回调函数放在异步任务队列中&#xff0c;是异步的&#xff0c;会在React渲染&#xff0c; dom 元素更新&#xff0c;浏览器绘制完成之后才会执行 useLayout…

multiprocessing多进程使用案例

multiprocessing — 基于进程的并行&#xff1a;https://docs.python.org/zh-cn/3.11/library/multiprocessing.html import sys from fastchat.serve.controller import Controller from fastchat.serve.model_worker import ModelWorker from fastchat.serve.openai_api_ser…

鸿蒙OSUniApp 开发实时天气查询应用 —— 鸿蒙生态下的跨端实践#三方框架 #Uniapp

使用 UniApp 开发实时天气查询应用 —— 鸿蒙生态下的跨端实践 在移动互联网时代&#xff0c;天气应用几乎是每个人手机中的"标配"。无论是出行、旅游还是日常生活&#xff0c;实时获取天气信息都极为重要。本文将以"实时天气查询应用"为例&#xff0c;详…

蓝桥杯178 全球变暖

题目描述 你有一张某海域 NxN 像素的照片&#xff0c;"."表示海洋、"#"表示陆地&#xff0c;如下所示&#xff1a; ....... .##.... .##.... ....##. ..####. ...###. ....... 其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上…

第五十二节:增强现实基础-简单 AR 应用实现

引言 增强现实(Augmented Reality, AR)是一种将虚拟信息叠加到真实世界的技术,广泛应用于游戏、教育、工业维护等领域。与传统虚拟现实(VR)不同,AR强调虚实结合,用户无需完全沉浸到虚拟环境中。本文将通过Python和OpenCV库,从零开始实现一个基础的AR应用:在检测到特定…