uni-app textarea获取光标位置不准确

uni-app textarea获取光标位置不准确

测试过的手机:

全部手机都是

操作步骤:

  • 正常操作

预期结果:

  • 跟文字一致吧

实际结果:

  • 文字占一个,表情占2个

bug描述:

textarea在失去焦点时的返回值里有光标最后出现的位置,e.detail.cursor,如果内容全都是文字的话,光标位置是对的,但是如果里面有添加表情的话,光标位置就不对了,具体看代码

![f1cd174392e57a88bb9c56e1ba9a4245](https://www.itying.com/uniimg.php?url=https://img-cdn-tc.dcloud.net.cn/uploads/questions/20240113/f1cd174392e57a88bb9c56e1ba9a4245.png

信息类别 详细信息
产品分类 uniapp/App
PC开发环境 Windows
版本号 11
HBuilderX Alpha
版本号 3.8.12
手机系统 全部
手机厂商 华为
页面类型 vue
vue版本 vue2
打包方式 云端
项目创建方式 HBuilderX

更多关于uni-app textarea获取光标位置不准确的实战教程也可以访问 https://www.itying.com/category-93-b0.html

7 回复

11111111

更多关于uni-app textarea获取光标位置不准确的实战教程也可以访问 https://www.itying.com/category-93-b0.html


浏览器 js 执行有问题吗,是 js 本身的问题,还是 app 里 js 执行的环境有问题?提供下测试文本

app端,我是文本里面有表情,光标移动到表情后面,失去焦点时位置就不对了

回复 传播星球: 我是说,浏览器 js 执行有问题吗,是 js 本身的问题,还是 app 里 js 执行的环境有问题?提供下测试文本

uni-app 中使用 textarea 组件时,确实可能会遇到获取光标位置不准确的问题。这通常是由于 textarea 的异步渲染或输入法(IME)处理导致的。以下是一些可能的解决方案和注意事项:

1. 使用 cursor 属性

textarea 组件提供了一个 cursor 属性,可以用来获取或设置光标的位置。你可以通过监听 input 事件来获取光标的位置。

<template>
  <textarea :value="value" @input="onInput" cursor="0"></textarea>
</template>

<script>
export default {
  data() {
    return {
      value: ''
    };
  },
  methods: {
    onInput(event) {
      this.value = event.detail.value;
      const cursorPosition = event.detail.cursor;
      console.log('光标位置:', cursorPosition);
    }
  }
};
</script>

2. 使用 selectionStartselectionEnd

你可以通过 textarea 的 DOM 元素直接获取 selectionStartselectionEnd 属性来获取光标的位置。

<template>
  <textarea ref="myTextarea" :value="value" @input="onInput"></textarea>
</template>

<script>
export default {
  data() {
    return {
      value: ''
    };
  },
  methods: {
    onInput(event) {
      this.value = event.detail.value;
      const textarea = this.$refs.myTextarea;
      const cursorPosition = textarea.selectionStart;
      console.log('光标位置:', cursorPosition);
    }
  }
};
</script>

3. 处理输入法(IME)问题

在某些情况下,尤其是在使用中文输入法时,光标位置可能会在输入过程中暂时不准确。这是因为输入法在输入未完成时(如拼音输入法在输入拼音但未选择汉字时)会占用光标位置。你可以通过监听 compositionstartcompositionend 事件来处理这种情况。

<template>
  <textarea ref="myTextarea" :value="value" @input="onInput" @compositionstart="onCompositionStart" @compositionend="onCompositionEnd"></textarea>
</template>

<script>
export default {
  data() {
    return {
      value: '',
      isComposing: false
    };
  },
  methods: {
    onInput(event) {
      if (!this.isComposing) {
        this.value = event.detail.value;
        const textarea = this.$refs.myTextarea;
        const cursorPosition = textarea.selectionStart;
        console.log('光标位置:', cursorPosition);
      }
    },
    onCompositionStart() {
      this.isComposing = true;
    },
    onCompositionEnd() {
      this.isComposing = false;
      this.onInput({ detail: { value: this.value } });
    }
  }
};
</script>

4. 延迟获取光标位置

如果以上方法仍然无法准确获取光标位置,你可以尝试在 setTimeout 中延迟获取光标位置,以确保 DOM 已经更新。

methods: {
  onInput(event) {
    this.value = event.detail.value;
    setTimeout(() => {
      const textarea = this.$refs.myTextarea;
      const cursorPosition = textarea.selectionStart;
      console.log('光标位置:', cursorPosition);
    }, 0);
  }
}

5. 使用第三方库

如果上述方法都无法解决问题,你可以考虑使用第三方库,如 textarea-caret-position,它可以帮助你更准确地获取和设置光标位置。

import getCaretCoordinates from 'textarea-caret-position';

methods: {
  onInput(event) {
    this.value = event.detail.value;
    const textarea = this.$refs.myTextarea;
    const cursorPosition = getCaretCoordinates(textarea, textarea.selectionStart);
    console.log('光标位置:', cursorPosition);
  }
}
回到顶部