H5: div与textarea输入框的交互(聚焦、失去焦点、键盘收起)

本文详细介绍了在H5中处理div与textarea交互的技巧,包括聚焦、失去焦点、键盘收起以及表情插入等功能的实现。针对输入框位置问题、键盘收起事件的处理和表情插入时保持聚焦状态等需求,提供了具体的解决方案和伪代码示例。
摘要由CSDN通过智能技术生成

简介

本文是基于 VUE3+TS 的代码说明。

记录自己遇到的 div 与 textarea 输入框交互的聚焦、失去焦点、键盘收起、表情插入不失去焦点的需求实现。

需求分析

在这里插入图片描述在这里插入图片描述

1.固定在页面底部;
2.默认显示纯文字与发送图标按钮,文字超出的省略显示;
3.点击文字后,显示文本输入框、表情、半透明遮罩层,自动聚焦;
4.有输入内容时,文本输入框右侧显示发送按钮;
5.点击表情,将表情加入到输入框最后,并且输入法键盘不收起;
6.输入框失去焦点、点击键盘上的收起或完成时,隐藏文本输入框和表情,显示默认的纯文字样式。

注意

------以下代码是伪代码------

1.输入框聚焦后,可能存在输入框位置不正确的问题

如输入框被遮挡、输入框没有挨着键盘等类似的问题。
这些问题在网上的解决方案较多,可自行查阅。

我的处理思路如下:

// html
<Teleport to="#inputPosition">
 <div v-show="isTextareaFocus" class="textarea-box">
    <!-- 输入框与发送按钮 -->
    <div>
      <textarea ref="textareaRef" />
      <button>发送</button>
    </div>
    <!-- 表情 -->
    <div>
      <div v-for="(emoji, index) in emojiList" :key="index">{
   {
    emoji }}</div>
    </div>
  </div>
</Teleport>

点击文本div时,显示文本输入框,并且自动聚焦

<script setup lang="ts">
  import {
    ref, nextTick } from 'vue'

  const isTextareaFocus = ref(false) // 文本输入框是否聚焦(即显示)
  const textareaRef = ref() // 输入框对应的DOM
  const emojiList = ['👍', '😀', '😮', '🥰', '😡', '🤣', '😤', '🙏'] // '🫡', '🫰🏻'

  /** 方法:输入框文本-是否聚焦、显示 */
  const displayTextarea = (display = false) => {
   
    isTextareaFocus.value = display
  }

  /** 操作:点击文本div */
  const handleToFocus = () => {
   
    displayTextarea(true)
    nextTick(() => {
   
      textareaRef.value?.focus() // 聚焦
      // 部分ios上添加表情后,光标不在最后位置的问题处理
      const length = message.value.length
      textareaRef.value?.setSelectionRange(length, length)
    })
  }
</script>

2.键盘按钮的收起,判断输入框是否失去焦点:

1)Android上,键盘按钮的收起,大部分不会触发输入框的blur事件,会触发webview的改变;
2)IOS上,键盘按钮的收起,会触发输入框的blur事件,大部分不会触发webview的改变;
3)点击表情时,也会导致输入框失去焦点。

我的处理思路如下:
1)默认都有的处理逻辑

/** 进行手势操作时的过滤处理:如点击、滑动等 */
const touchStartEvent = (e: Event) => {
   
  const target = e.target as HTMLElement
  // 这里包含textareaBtn,是为了发送按钮的点击事件能正常触发
  if (target.id === 'emoji' || target.id === 'textareaBtn') {
   
    isNeedFocus.value = true
  } else {
   
    isNeedFocus.value = false
  }
}

2)ios的特殊处理逻辑

if (val) {
   
  // 键盘弹起
  const focusEl = textareaRef.value
  if (focusEl) {
   
    focusEl.scrollIntoView({
    block: 'center' })
  }
 } else {
   
  // 键盘收起
  clickBlur()
}

3.表情的插入

整个列表、文本输入框盒子添加touchstart事件,最先执行的是touchstart,根据当前touch事件的触发dom的id,判断是否需要保留文本输入框的聚焦;然后执行的表情的点击事件以及文本输入框的失去焦点事件,其中:
1)touchStartEvent
判断触发的dom的id是否是需要保留聚焦的dom,做一个标记;
2)handleInsertEmoji
做表情的插入,以及对文本输入框的聚焦;
3)handleToBlur
做输入框失去焦点的逻辑处理,根据1)中的标记,进行逻辑处理(之所以要重置标记,是为了下次输入框能正常失去焦点)。

// html
<div class="page" @touchstart="touchStartEvent">
  ...
  <!-- 文本输入框、表情栏 -->
  <Teleport to="#inputPosition">
    <div v-show="isTextareaFocus" class="textarea-box" @touchstart="touchStartEvent">
      ...
        <textarea @blur="handleToBlur" />
      ...
      <!-- 表情 -->
      <div class="emoji-list">
        <div
          id="emoji"
          v-for="(emoji, index) in emojiList"
          :key="index"
          @click.stop="handleInsertEmoji(emoji)"
          >{
   {
    emoji }}</div
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值