동경 2023-12-03 18:27 采纳率: 0%
浏览 21
已结题

div editable中的光标问题

需求: #话题功能

预期

1、当我输入 #号紧跟着的文案要高亮

2、复制文案粘贴文案也要保持之前的状态,比如 复制 #文案#文案1,粘贴后也要 #文案#文案1

目前遇到的问题:

当我输入文案
光标会自动会跳到最前面,应该是使用了innerHTML的原因,所以光标默认移动到最前面。
我想要的是光标紧跟着文案,跟textarea一样

下面是代码点击此链接跳到sandbox

<script setup lang="ts">
import { ref, reactive, watch, watchEffect, onMounted } from "vue";
const editableDiv = ref<any>(null);
const formState = reactive<any>({
  description: "",
});

// 触发描述框 input事件
const handleDescInput = () => {
  const result = document.createElement("p");
  const content = editableDiv.value.textContent;

  if (!isComposing) {
    for (let i = 0; i < content.length; i++) {
      const char = content[i];

      if (char === "#") {
        let hashtag = char;
        i++;

        while (
          i < content.length &&
          content[i] !== " " &&
          content[i] !== "#" &&
          content[i] !== "\n"
        ) {
          hashtag += content[i];
          i++;
        }

        if (hashtag.length > 1) {
          // 创建span元素并设置样式和内容
          var span = document.createElement("span");
          span.className = "hashtag";
          span.innerText = hashtag;
          console.log("hashtag", hashtag);
          // 将span元素添加到可编辑div中
          result.appendChild(span);
        } else {
          result.appendChild(document.createTextNode(char));
        }

        i--;
      } else {
        result.appendChild(document.createTextNode(char));
      }
    }
  }

  formState.description = result.innerHTML;
};

// 添加paste事件监听器,以便处理粘贴
const handleDescPaste = (e) => {
  // 阻止默认粘贴行为
  e.preventDefault();
  // 获取粘贴的纯文本内容
  var pastedText = (e.originalEvent || e).clipboardData.getData("text/plain");

  // 在粘贴的文本中插入换行符
  pastedText = pastedText.replace(/\s+/g, "\n");

  // 将处理后的文本插入可编辑div
  document.execCommand("insertText", false, pastedText);
};

let isComposing = false;
// 处理中文输入法的组合开始事件
const handleCompositionStart = () => {
  console.log("正在组织...");
  isComposing = true;
};

// 处理中文输入法的组合结束事件
const handleCompositionEnd = () => {
  console.log("结束组织...");
  isComposing = false;
  handleDescInput();
};
</script>

<template>
  <div
    ref="editableDiv"
    class="editableDiv"
    contenteditable="true"
    @input="handleDescInput"
    @paste="handleDescPaste"
    @compositionend="handleCompositionEnd"
    @compositionstart="handleCompositionStart"
    v-html="formState.description"
  ></div>
</template>

<style scoped>
.editableDiv {
  border: 1px solid;
  width: 1000px;
  height: 60px;
  border: 1px solid;
  text-align: left;
  caret-color: red;
}
</style>

<style>
.hashtag {
  color: red !important;
}
</style>
  • 写回答

15条回答 默认 最新

报告相同问题?

问题事件

  • 系统已结题 12月11日
  • 创建了问题 12月3日

悬赏问题

  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题