동경 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日

悬赏问题

  • ¥50 xslt如何让block撑满页面
  • ¥15 vs的显示无法启动IIS Express Web服务器,怎么解决?
  • ¥20 一个python博客项目的相关图例
  • ¥15 轮廓提取也提取不到,有没有别的方法,如何解决?
  • ¥50 Js和c++如何将含有图片的excel文件上传到后台服务器
  • ¥15 光电神经网络,FPGA
  • ¥20 通过防火墙出入站阻止游戏程序联网失效
  • ¥15 鼠标是可以在QT界面上移动的,但是热拔插鼠标无法移动了同时板子上是没问题的,如何解决?
  • ¥15 iframe嵌套显示问题
  • ¥20 【UE4】别人打包好的ue4游戏我该如何在自己的ue4引擎上运行