h5完成一个吸附在键盘上的工具栏

news/2025/10/14 19:09:51/文章来源:https://www.cnblogs.com/tlnshuju/p/19141803

h5完成一个吸附在键盘上的工具栏

2025-10-14 19:00  tlnshuju  阅读(0)  评论(0)    收藏  举报

<template>
<div class="keyboard-toolbar-container">
<!-- 聊天内容区域 -->
<div class="chat-container">
<h2 class="chat-title">聊天示例</h2>
<div class="messages" ref="messagesContainer">
<div class="message received">
<img src="https://picsum.photos/id/1005/40/40" alt="对方头像" class="avatar">
<div class="message-content">你好!这个工具栏会在你点击输入框时展示在键盘上方</div>
</div>
<div class="message sent">
<div class="message-content">看起来很不错,有哪些能力呢?</div>
<img src="https://picsum.photos/id/1012/40/40" alt="我的头像" class="avatar">
</div>
<div class="message received">
<img src="https://picsum.photos/id/1005/40/40" alt="对方头像" class="avatar">
<div class="message-content">有表情、图片、文件等常用功能,试试看吧!</div>
</div>
</div>

<!-- 输入区域 -->
<div class="input-area">
<textarea
v-model="message"
@focus="showToolbar = true"
@blur="onInputBlur"
placeholder="输入消息..."
ref="messageInput"
></textarea>
<button @click="sendMessage" class="send-btn">发送</button>
</div>
</div>

<!-- 吸附在键盘上的工具栏 -->
<div
class="toolbar"
:class="{ 'toolbar-visible': showToolbar, 'toolbar-hidden': !showToolbar }"
>
<button class="toolbar-btn" @click="handleToolClick('emoji')">
<i class="fa fa-smile-o"></i>
<span>表情</span>
</button>
<button class="toolbar-btn" @click="handleToolClick('image')">
<i class="fa fa-picture-o"></i>
<span>图片</span>
</button>
<button class="toolbar-btn" @click="handleToolClick('file')">
<i class="fa fa-file-o"></i>
<span>文件</span>
</button>
<button class="toolbar-btn" @click="handleToolClick('mic')">
<i class="fa fa-microphone"></i>
<span>语音</span>
</button>
<button class="toolbar-btn" @click="handleToolClick('location')">
<i class="fa fa-map-marker"></i>
<span>位置</span>
</button>
<button class="toolbar-btn" @click="handleToolClick('more')">
<i class="fa fa-ellipsis-h"></i>
<span>更多</span>
</button>
</div>
</div>
</template>

<script>
export default {
name: 'KeyboardToolbar',
data() {
return {
message: '',
showToolbar: false,
// 用于追踪是否点击了工具栏按钮
toolbarClicked: false
};
},
methods: {
// 处理输入框失焦事件
onInputBlur() {
// 延迟隐藏工具栏,防止点击工具栏按钮时立即隐藏
setTimeout(() => {
if (!this.toolbarClicked) {
this.showToolbar = false;
}
this.toolbarClicked = false;
}, 200);
},

// 处理工具栏按钮点击
handleToolClick(type) {
this.toolbarClicked = true;
console.log(`点击了${this.getToolName(type)}工具`);

// 可以根据不同类型执行不同运行
switch(type) {
case 'emoji':
// 显示表情选择器逻辑
break;
case 'image':
// 选择图片逻辑
break;
case 'file':
// 选择文件逻辑
break;
// 其他工具的处理逻辑...
}

// 点击后重新聚焦到输入框
this.$refs.messageInput.focus();
},

// 获取软件名称
getToolName(type) {
const toolNames = {
emoji: '表情',
image: '图片',
file: '文件',
mic: '语音',
location: '位置',
more: '更多'
};
return toolNames[type] || type;
},

// 发送消息
sendMessage() {
if (!this.message.trim()) return;

// 创建新消息元素
const newMessage = document.createElement('div');
newMessage.className = 'message sent';
newMessage.innerHTML = `
<div class="message-content">${this.message}</div>
<img src="https://picsum.photos/id/1012/40/40" alt="我的头像" class="avatar">
`;

// 添加到消息容器并滚动到底部
this.$refs.messagesContainer.appendChild(newMessage);
this.$refs.messagesContainer.scrollTop = this.$refs.messagesContainer.scrollHeight;

// 清空输入框
this.message = '';
}
},
mounted() {
// 监听窗口 resize 事件,处理键盘表现/隐藏
window.addEventListener('resize', () => {
const isInputFocused = document.activeElement === this.$refs.messageInput;
if (isInputFocused) {
this.showToolbar = true;
// 调整滚动位置,确保输入框可见
setTimeout(() => {
this.$refs.messagesContainer.scrollTop = this.$refs.messagesContainer.scrollHeight;
}, 300);
}
});
},
beforeDestroy() {
window.removeEventListener('resize', () => {});
}
};
</script>

<style scoped>
.keyboard-toolbar-container {
display: flex;
flex-direction: column;
height: 100vh;
overflow: hidden;
background-color: #f5f5f5;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

.chat-container {
flex: 1;
display: flex;
flex-direction: column;
padding: 16px;
overflow: hidden;
}

.chat-title {
text-align: center;
margin: 0 0 16px 0;
color: #333;
font-weight: 600;
}

.messages {
flex: 1;
overflow-y: auto;
margin-bottom: 16px;
display: flex;
flex-direction: column;
gap: 12px;
}

.message {
display: flex;
max-width: 80%;
word-break: break-word;
}

.message.received {
align-self: flex-start;
}

.message.sent {
align-self: flex-end;
flex-direction: row-reverse;
}

.avatar {
width: 40px;
height: 40px;
border-radius: 50%;
margin: 0 8px;
}

.message-content {
padding: 10px 14px;
border-radius: 18px;
line-height: 1.4;
}

.message.received .message-content {
background-color: #ffffff;
border-top-left-radius: 4px;
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
}

.message.sent .message-content {
background-color: #007aff;
color: white;
border-top-right-radius: 4px;
}

.input-area {
display: flex;
gap: 8px;
align-items: flex-end;
}

.input-area textarea {
flex: 1;
border: 1px solid #ddd;
border-radius: 20px;
padding: 12px 16px;
resize: none;
outline: none;
font-size: 16px;
min-height: 42px;
max-height: 120px;
}

.send-btn {
background-color: #007aff;
color: white;
border: none;
border-radius: 50%;
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-weight: bold;
}

/* 工具栏样式 */
.toolbar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
background-color: white;
display: flex;
justify-content: space-around;
padding: 8px 0;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
z-index: 100;
}

.toolbar-hidden {
transform: translateY(100%);
opacity: 0;
}

.toolbar-visible {
transform: translateY(0);
opacity: 1;
}

.toolbar-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: none;
border: none;
color: #666;
font-size: 12px;
padding: 6px;
width: 50px;
cursor: pointer;
}

.toolbar-btn i {
font-size: 20px;
margin-bottom: 4px;
}

.toolbar-btn:active {
background-color: #f0f0f0;
border-radius: 8px;
}
</style>

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

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

相关文章

【通达信L2黑科技】 用 DLL 把 10 年机构大单净额 1 秒拖进本地,选股、排序、回测快到飞起!

【通达信L2黑科技】 用 DLL 把 10 年机构大单净额 1 秒拖进本地,选股、排序、回测快到飞起!引言 通达信L2数据中,有一个L2_AMO资金流向函数:类型:资金流向函数 功能:成交额分档 描述:单数分档,按:N(0--3):超…

详细介绍:iCloud照片共享:在家庭内外分享iCloud照片

详细介绍:iCloud照片共享:在家庭内外分享iCloud照片pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…

Flink 有状态流处理State、Keyed State、Checkpoint、对齐/不对齐与生产实践 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

对static新的认识

学习java时,我首先声明了一个统一响应结果的实体类: public Result success(Object object){Result result = new Result();result.code=1;result.msg="success";result.data=object;return result;}然后调…

C++STL之stack,queue与容器适配器 - 教程

C++STL之stack,queue与容器适配器 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "…

2025年氧化镁厂家最新推荐排行榜,电工级/高温/低温/中温/防火电缆/矿物绝缘/熔盐加热器/电热管用/单头管用/合成云母用氧化镁公司推荐!

随着工业技术的不断进步,氧化镁在各个领域的应用越来越广泛。从电工级氧化镁到高温、低温、中温氧化镁,再到防火电缆氧化镁、矿物绝缘氧化镁、熔盐加热器氧化镁、电热管用氧化镁、单头管用氧化镁以及合成云母用氧化镁…

智能体分析

AI智能体技术正经历快速发展,从早期的简单对话机器人演进为能够自主规划、执行复杂任务的多模态系统。本次将对市面上功能较为完善的智能体平台进行系统分析,从通用型、垂直领域、开源/免费工具三个维度,对比它们的…

Excel - lookup()

Excel - lookup() Excel lookup(B3, sheet2!A3:A33, sheet2!E3:E33), 向下填充时如何只增加第1个参数值?例如增加B3为B4, B5...,保持sheet2!A3:A33, sheet2!E3:E33不变。 ChatGPT said:你这个问题是 Excel 相对/绝对…

2025 年玄武岩厂家推荐榜:玄武岩/0-3mm/3-5mm/5-10mm/10-15mm/10-20mm/石子厂,聚焦基建升级与高端化需求,山东展飞建筑材料有限公司成优选

随着国内基建工程持续推进(高铁、高速、市政项目等)、绿色建材标准趋严及高端新材料需求逐步释放,玄武岩建筑材料凭借高强度、耐磨损等特性,已从传统基建专属逐步拓展至道路铺建、景观绿化、污水治理等多个领域,2…

2025 佛山铝合金/系统/断桥铝/耐用/推拉/封阳台/别墅/静音门窗厂家品牌实力推荐:聚焦技术与服务的五大优选标杆

在家居装修与建筑工程中,门窗的性能与品质直接影响居住舒适度与建筑安全性。随着行业向 "科技美学" 升级,兼具技术创新、品质保障与服务能力的品牌愈发受到关注。以下结合市场调研与实际应用场景,推荐五个…

Ubuntu22.04 server网络配置

配置ubuntu ip地址新安装的 Ubuntu 服务器首需要配置 ip 才能进行网络连接。 1 配置 IP 1.1 查看网卡信息 sudo apt install lshw -y sudo lshw -C network例如我这里使用有线网网卡名是 enp3s01.2 配置 ip 编辑 netpl…

完整教程:深度学习优化器全面指南:核心参数选择与实战策略

完整教程:深度学习优化器全面指南:核心参数选择与实战策略pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Conso…

C#——方法的定义、调用与调试 - 详解

C#——方法的定义、调用与调试 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mona…

说说新版畅联云的一些重要约定

先了解几个基本概念:品目类似文件夹,而且从顶级来看,畅联将AIoT分成了3大分类,一个是视频设备,一个是IoT设备,一个是算法。品目是无限级的,可以一层层建一下。产品产品属于某一个具体品目,譬如某个4G安全帽产品…

App.vue(完整可运行示例)

🔧 TXT 文件 URL 批量替换工具将文件中的 https://alicdn-imags.zsgw.vip/default/20250826/imags 替换为 https://site.shrtxs.cn/agent <div><inputtype="file"ref="fileInput"@chan…

Windows MySQL 报错

1. 首次更改密码报错解决 ERROR 1820 (HY000) ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement. 问题解决修改密码 ALTER USER username@host IDENTIF…

Redis:高性能内存数据库的六大核心优势 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

lvgl刷新回调事件实现说明

static void my_lvgl_flush_cb(lv_disp_drv_t* disp_drv, const lv_area_t* area, lv_color_t* color_p) {lock(1); #if 1uint32_t offset = 0;int32_t x, y;for (y = area->y1; y <= area->y2; y++) {for (x…

Avalonia Behaviors 在 StackPanel 空白处无效问题解析与解决方案

问题描述 在 Avalonia UI 开发中,很多开发者会遇到这样的问题:在 StackPanel 上添加了 Behaviors 和事件触发器,但是只有在 StackPanel 内部的文本、按钮等可视化元素上点击才有效,而在 StackPanel 的空白区域点击…

完整教程:Django 入门:快速构建 Python Web 应用的强大框架

完整教程:Django 入门:快速构建 Python Web 应用的强大框架pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Cons…