当前位置: 首页 > news >正文

h5实现一个吸附在键盘上的工具栏

<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.dtcms.com/a/418223.html

相关文章:

  • 解决 sqlplus / as sysdba 登录缓慢问题
  • Mysql DBA学习笔记(主从复制)
  • 网站开发的交付文档企业策划是什么意思
  • 个人网站主机选择上海品牌全案设计公司
  • 布谷娱乐直播系统源码开发实用功能:技术驱动更迭的创新体验
  • ArcGIS JSAPI 高级教程 - 高亮效果优化之开启使用多高亮样式
  • 元宇宙的搜索引擎:如何在虚拟世界中查找信息
  • Unity-AB包
  • Rust开发环境配置
  • 【mdBook】5.2.1 通用配置
  • Rust自定义函数引用
  • Java 集合体系 —— List 篇
  • 操作系统应用开发(十一)RustDesk在线编译自己客户端——东方仙盟筑基期
  • 【mdBook】5.2 配置
  • 网站建设难么让网站快速收录
  • h5游戏网站建设游戏软件开发培训学校
  • 扩散模型-图像编辑【An Edit Friendly DDPM Noise Space: Inversion and Manipulations】
  • 开源 C# 快速开发(九)通讯--Tcp客户端
  • 大黄蜂云课堂vep格式加密视频录屏截图翻录转换为mp4
  • 【Python办公】批量图片转PDF工具
  • Python爬虫实战:获取北京市交管局最新车检信息与数据分析
  • ubuntu24.04 实现DLNA音频推送
  • 企业网站的建设规划网站建站前期准备工作
  • Docker搭建ESPIDF环境,程序下载
  • MQTT-物联网轻量级通信
  • eclipse复制项目后原项目名依然伴随值所复制的项目名
  • 微服务架构:从单机到分布式的革命性升级
  • 【ROS2学习笔记】话题通信篇:python话题订阅与发布
  • 【碎片化学习】SpringBoot服务的启动过程
  • 儿童网站模板 html做百度快照要先有网站吗