uniapp 小程序 textarea 层级穿透,聚焦光标位置错误怎么办?

news/2025/1/16 7:44:22/

前言

在开发微信小程序时,使用 textarea 组件可能会遇到一些棘手的问题。最近我在使用 uniapp 开发微信小程序时,就遇到了两个非常令人头疼的问题:

  1. 层级穿透:由于 textarea 是原生组件,任何元素都无法遮盖住它。当其他元素与 textarea 重叠时,就会出现层级穿透的问题。特别是在弹窗中使用 textarea 时,如果弹窗有动画效果,textarea 会在动画执行期间显示在页面右上角,导致视觉效果非常差。如果等到动画结束后再显示 textarea,又会出现突然弹出的效果,影响用户体验。
  2. 光标位置不正确:在 iOS 设备上,textarea 的光标默认会出现在文本的最前面。当文本较长时,点击文本中间位置时光标仍然会出现在最前面,弹出键盘后很难重新定位到需要编辑的位置,使用体验非常糟糕。

为了解决这些问题,我尝试了多种方案,但效果都不尽如人意。最终,我发现可以使用 editor 富文本编辑器组件来替代 textarea,它不仅解决了上述问题,还提供了更多的自定义选项。

封装 Editor 组件

editor 富文本编辑器组件不仅可以实现多行文本输入,还能避免层级穿透和光标位置错误的问题,甚至可以自定义光标的颜色。

官方对 editor 组件的介绍如下:

富文本编辑器,可以对图片、文字格式进行编辑和混排。

既然 editor 是一个富文本编辑器,那么它自然可以处理带有格式的文本。我们可以通过降级使用,将其作为一个普通的文本输入框,输入和输出的内容都是纯文本。

我的实现代码如下:

<template><view class="relative"><!-- 编辑器区域 --><editor:id="editorId":model-value="htmlContent"class="w-full bg-gray-50/50 rounded-xl p-3 text-sm min-h-[120px] text-base":placeholder="placeholder || '请输入内容...'"@ready="onEditorReady"@input="handleInput":read-only="isReadOnly"/></view>
</template><script setup lang="ts">
import { EditorContext } from '@/types/global'
import nanoid from '@/utils/nanoid'const props = defineProps<{modelValue: stringplaceholder?: stringid?: string
}>()const emit = defineEmits<{(e: 'update:modelValue', value: string): void(e: 'blur'): void
}>()// 编辑器内部 HTML 内容
const htmlContent = ref(props.modelValue)
// 编辑器上下文
const editorCtx = ref<EditorContext | null>(null)
const isReadOnly = ref(true)// 生成唯一 id
const editorId = computed(() => props.id || `editor-${nanoid()}`)
const instance = getCurrentInstance()// 初始化编辑器
const onEditorReady = () => {uni.createSelectorQuery().in(instance).select(`#${editorId.value}`).context((res: any) => {editorCtx.value = res.context// 只设置初始内容,不自动聚焦if (editorCtx.value && props.modelValue) {editorCtx.value.setContents({ html: props.modelValue })}isReadOnly.value = false}).exec()
}// 处理输入
const handleInput = (e: any) => {// 保存 HTML 内容htmlContent.value = e.detail.html || ''// 向外发送纯文本emit('update:modelValue', e.detail.text || '')
}defineExpose({editorCtx,
})
</script><style scoped>
:deep([id^='editor']) {caret-color: rgb(99, 102, 241);
}
</style>

如果你有需要可以直接复制使用,作为组件引入。这里面有几个注意点我介绍一下:

  1. 默认的 readonlytrue ,在编辑器准备完成后修改为 true,这个逻辑是因为 setContent 设置内容时会自动聚焦,设置为 readonly: false 就不会触发自动聚焦了,如果你需要自动聚焦可以将这段逻辑移除掉。
  2. 默认暴露了 editorCtx 如果你想主动修改编辑器内容可以触发 editorCtx.setContent 去修改,而不是直接修改 modelValue,因为内部并没有监听 modelValue 的实时变化去修改编辑器,避免多处地方同时修改编辑器内容。
  3. :deep([id^='editor']) { caret-color: rgb(99, 102, 241); }:用于修改编辑器中光标颜色,因为我这里支持自定义 id ,所以匹配了所有 editor 前缀。

通过将 textarea 替换为 editor 后,你会发现效果都是一样的,而且在 ios 端的使用体验会好很多,手指点击哪里,光标的默认位置就在哪里,在效果如下图所示。

image.png

💡注意点editor 组件在 focus 时在 ios 设备上是不会获取到键盘高度的,因此如果你有工具栏放在键盘上的需求,在替换组件时需要慎重考虑。

总结

如果你想查看 editor 组件的实际效果,可以搜索学习卡盒小程序,在卡片页面长按编辑尝试一下,看看效果是否符合你的需求。希望这篇文章能帮助你解决遇到的问题。如果对你有帮助,欢迎点赞支持!


http://www.ppmy.cn/news/1563549.html

相关文章

2501C++,现代C++大大提高开发效率

提升开发效率的一些语法糖: 1.if/switch初化语句 //以前 auto*tmp parseExpression(); if(tmp!nullptr){work(); } //之后if (auto* tmp parseExpression(); tmp ! nullptr) {work(); }2.结构化绑定 std::tuple<int,string> nextToken(){return {4,"直降"…

【机器学习:十四、TensorFlow与PyTorch的对比分析】

1. 发展背景与社区支持 1.1 TensorFlow的背景与发展 TensorFlow是Google于2015年发布的开源深度学习框架&#xff0c;基于其前身DistBelief系统。作为Google大规模深度学习研究成果的延续&#xff0c;TensorFlow从一开始就定位为生产级框架&#xff0c;强调跨平台部署能力和性…

Leetcode2270:分割数组的方案数

题目描述&#xff1a; 给你一个下标从 0 开始长度为 n 的整数数组 nums 。 如果以下描述为真&#xff0c;那么 nums 在下标 i 处有一个 合法的分割 &#xff1a; 前 i 1 个元素的和 大于等于 剩下的 n - i - 1 个元素的和。下标 i 的右边 至少有一个 元素&#xff0c;也就是…

【Leetcode 每日一题】3065. 超过阈值的最少操作数 I

问题背景 给你一个下标从 0 0 0 开始的整数数组 n u m s nums nums 和一个整数 k k k。 一次操作中&#xff0c;你可以删除 n u m s nums nums 中的最小元素。 你需要使数组中的所有元素都大于或等于 k k k&#xff0c;请你返回需要的 最少 操作次数。 数据约束 1 ≤ n …

华为数通HCIE备考经验分享

在分享我的考试心得前我先介绍一下我自己&#xff0c;我叫郑同学&#xff0c;22岁&#xff0c;就读于深圳信息职业技术学院移动通信技术专业&#xff0c;在2024年的9月&#xff0c;我成功获得了HCIE-Datacom证书。 考证契机 我的备考之旅始于去年2023年的华为ICT大赛。在这场…

k8s基础(6)—Kubernetes-存储

Kubernetes-存储概述 k8s的持久券简介 Kubernetes的持久卷&#xff08;PersistentVolume, PV&#xff09;和持久卷声明&#xff08;PersistentVolumeClaim, PVC&#xff09;为用户在Kubernetes中使用卷提供了抽象。PV是集群中的一块存储&#xff0c;PVC是对这部分存储的请求。…

国产游戏行业的挑战与机遇:IT技术如何引领未来

近年来&#xff0c;国产游戏行业如同一颗璀璨的新星&#xff0c;在全球游戏市场中冉冉升起。从早期的模仿与跟随&#xff0c;到如今的多领域技术创新&#xff0c;中国游戏开发者展现出了非凡的实力与潜力。然而&#xff0c;面对全球市场的激烈竞争&#xff0c;国产游戏技术仍面…

Linux下部署Redis(Docker部署超详细)

docker search redisdocker pull redis:6.2.6 提前在服务器建立 /data/redis 文件夹&#xff0c;touch 文件redis.conf&#xff0c;也可以上面的直接复制 然后去github官网去复制对应版本的conf文件: redis/redis.conf at 6.2.6 redis/redis GitHub 得到conf文件后&#xf…