contenteditable实现插入标签的输入框功能(Vue3版)

需求:实现一个简易的函数编辑器

  1. 点击参数能够往输入框插入标签
  2. 点击函数能够往输入框插入文本
  3. 删除能够把标签整体删除
  4. 输入的参数能够获取到其携带的信息
    在这里插入图片描述
    在这里插入图片描述

插入文本

/**
 * @description 点击函数展示到输入框
 */
const getValue = ({ item, type }: any) => {
  // 创建一个文本节点
  const textNode = document.createTextNode(item.value);
  // 在光标位置插入文本节点
  range.value!.insertNode(textNode);
  // 移动光标到文本节点的末尾
  range.value?.setStartAfter(textNode);
  // 折叠光标到文本节点的末尾
  range.value?.collapse(true);
  // 移除所有选区 不移除selection会到聚焦点击的文本
  selection.value?.removeAllRanges();
  // 添加选区
  selection.value?.addRange(range.value!);
};

插入标签

/**
 * @description 点击参数展示到输入框
 */
const getSpanTag = (params: DatabaseManagementParamsForm) => {
  // 创建前缀
  let prefix = `<span contenteditable="false" disabled="disabled" class="el-tag el-tag--primary el-tag--small fn-param" data-param="${params.id}">`;
  // 创建后缀
  let suffix = "</span>";
  // 创建span元素
  let el = document.createElement("span");
  // 将前缀和后缀插入span元素
  el.innerHTML = prefix + params.abbreviation + suffix;
  // 去掉外层的span
  let frag = document.createDocumentFragment();
  let node = frag.appendChild(el.firstChild!);
  // 插入tag
  range.value?.insertNode(node);
  // 设置光标
  range.value?.setStartAfter(node);
  range.value?.collapse(true);
  // 不移除selection会到聚焦点击的文本
  selection.value?.removeAllRanges();
  // 添加选区
  selection.value?.addRange(range.value!);
};

提交获取数据

/**
 * @description 获取构建的html里面的文本和参数
 */
const getTextAndParams = () => {
  // 获取文本中的参数元素
  const paramsEls = textRef.value?.getElementsByClassName("fn-param");
  // 获取文本的innerHTML
  let innerHTML = textRef.value!.innerHTML;
  // 定义参数数组
  const params = [];
  // 如果参数元素存在
  if (paramsEls) {
    // 遍历参数元素
    for (let index = 0; index < paramsEls.length; index++) {
      // 将参数元素转换为HTMLSpanElement类型
      const element = paramsEls[index] as HTMLSpanElement;
      // 获取参数元素在innerHTML中的索引
      const idx = innerHTML.indexOf(element.outerHTML);
      // 将参数元素添加到参数数组中
      params.push({
        name: element.innerText,
        id: element.dataset.param,
        index: idx,
      });
      // 将参数元素的outerHTML替换为innerHTML
      innerHTML = innerHTML.replace(element.outerHTML, element.innerText);
    }
  }
  // 返回文本和参数数组
  return {
    text: textRef.value!.innerText,
    params,
  };
};

在这里插入图片描述

index标记tag位置,避免重复无法渲染识别

数据回显

/**
 * @description 根据数据回显
 */
const reviewFn = (data: FnEditorData) => {
  // 获取data中的fn和params
  const { fn, params } = data;
  // 定义innerHTML,初始值为fn
  let innerHTML = fn;
  // 定义idx,初始值为0
  let idx = 0;
  // 遍历params,将每个param的name插入到innerHTML中
  params.forEach((item) => {
    // 定义prefix,用于创建span标签
    let prefix = `<span contenteditable="false" disabled="disabled" class="el-tag el-tag--primary el-tag--small fn-param" data-param="${item.id}">`;
    // 定义suffix,用于结束span标签
    let suffix = "</span>";
    // 定义tag,用于拼接prefix和suffix
    const tag = prefix + item.name + suffix;
    // 使用正则替换innerHTML中的item.name,替换为tag
    innerHTML = innerHTML.replaceAll(item.name, (match, offset) => {
      // 如果offset等于item.index加上idx,则替换为tag
      if (offset === item.index + idx) {
        return tag;
      }
      // 否则,返回match
      return match;
    });
    // 将tag的长度减去item.name的长度,加到idx上
    idx += tag.length - item.name.length;
  });
  // 延迟执行,将innerHTML设置到textRef的value上
  nextTick(() => {
    textRef.value!.innerHTML = innerHTML;
  });
};

目前只是简单的demo,如果涉及到公式渲染就是另外的价钱了,数学公式渲染参考katex

在线浏览
代码仓库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/678885.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络之crc循环冗余校验、子网划分、rip协议路由转发表、时延计算、香浓定理 奈氏准则、TCP超时重传 RTO

crc循环冗余校验 异或运算 : 相同得0,相异得1 从多项式获取除数 在原数据的末端补0 , 0的个数等于最高次项的阶数 如果最后结果的有效位数较少时&#xff0c;前面应该补0&#xff0c;补到个数与阶位相同 子网划分 子网掩码&#xff1a;用于识别IP地址中的网络号和主机号的…

MySQL数据库整体知识点简述

目录 第一章&#xff1a;数据库系统概述 第二章&#xff1a;信息与数据模型 第3章 关系模型与关系规范化理论 第四章——数据库设计方法 第六-七章——MySQL存储引擎与数据库操作管理 第九章——索引 第10章——视图 第11章——MySQL存储过程与函数 第12章——MySQL 触…

深度解析:ISP代理与住宅代理区别

代理充当用户和互联网之间的中介&#xff0c;提供各种功能以增强安全性、隐私性和可访问性。在众多代理类型中&#xff0c;ISP 和住宅代理脱颖而出&#xff0c;每种代理都具有独特的功能和应用。 了解 ISP 代理 代理ISP&#xff0c;通常称为互联网服务提供商代理&#xff0c;通…

打造高效问答系统:合合信息文档解析工具的应用与实践

官.网地址&#xff1a;合合TextIn - 合合信息旗下OCR云服务产品 LLM&#xff08;大型语言模型&#xff09;的应用落地正快速推动着各行各业工作模式的革新。根据埃森哲在2023年发布的研究报告&#xff0c;预计全行业中有40%的工作时间将得到大语言模型的支持与协助。通过引入A…

23种模式之一— — — —适配器模式的详细介绍与讲解

适配器介绍与讲解 一、概念二、适配器模式结构适配器分类核心思想核心角色模式的UML类图应用场景模式优点模式缺点 实例演示图示代码演示运行结果 一、概念 适配器模式&#xff08;别名&#xff1a;包装器&#xff09; 是一种结构型设计模式 将一个类的接口转换成客户希望的另…

存内计算与扩散模型:下一代视觉AIGC能力提升的关键

目录 前言 视觉AIGC的ChatGPT4.0时代 扩散模型的算力“饥渴症” 存内计算解救算力“饥渴症” 结语 前言 ​ 在这个AI技术日新月异的时代&#xff0c;我们正见证着前所未有的创新与变革。尤其是在视觉内容生成领域&#xff08;AIGC&#xff0c;Artificial Intelligence Generate…

家政预约小程序12用户登录

目录 1 创建全局变量2 创建页面3 搭建页面4 实现登录逻辑总结 在小程序中&#xff0c;登录是一个常见的场景。比如我们在小程序预约或者购买时&#xff0c;通常要求用户先登录后购买。如果使用传统方案&#xff0c;登录这个动作其实最终的目的是为了获取用户的openid。而使用低…

如何理解与学习数学分析——第一部分——数学分析概观

第1 部分&#xff1a;数学分析概观(Studying Analysis) 1. 数学分析之面目(What is Analysis like?) 本章说明了分析中的定义、定理和证明。 它介绍了一些符号&#xff0c;并解释了如何使用数学分析中的这些数学符号和数学词汇、以及应该把它们读成什么。它指出了这种类型的…

【通俗易懂搞算法】一篇文章弄懂Manacher算法

Manacher算法 manacher算法解决的问题回文 最长回文子串最长回文子串解法解法1.0解法2.0Manacher算法回文半径、回文直径回文半径数组之前扩的所有位置中所到达的最右回文右边界(R)取得更远边界的中心点的位置(C)Manacher算法优化情形Manacher算法优化情形总结 manacher算法代码…

PySpark特征工程(I)--数据预处理

有这么一句话在业界广泛流传&#xff1a;数据和特征决定了机器学习的上限&#xff0c;而模型和算法只是逼近这个上限而已。由此可见&#xff0c;特征工程在机器学习中占有相当重要的地位。在实际应用当中&#xff0c;可以说特征工程是机器学习成功的关键。 特征工程是数据分析…

工业网关有效解决企业在数据采集、传输和整合方面的痛点问题-天拓四方

一、企业背景概述 随着信息技术的飞速发展&#xff0c;工业互联网已成为推动制造业转型升级的关键力量。在众多工业企业中&#xff0c;某公司凭借其深厚的技术积淀和广阔的市场布局&#xff0c;成为行业内的佼佼者。然而&#xff0c;在数字化转型的道路上&#xff0c;该公司也…

Java中getBytes()方法

我以为旅人将我 热情都燃尽 —— 24.6.4 String.getBytes(String decode)方法会根据指定的decode编码返回某字符串在该编码下的byte数组表示 而与getBytes相对的&#xff0c;可以通过new String(byte[], decode)的方式来还原这个“深”字时&#xff0c;这个new String(byte[],…

【UML用户指南】-07-对基本结构建模-公共机制

目录 1、术语和概念 1.1、注解&#xff08;note&#xff09; 1.2、修饰 1.3、衍型 1.4、标记值 1.5、约束 1.6、标准元素 1.7、外廓&#xff08;profile&#xff09; 2、对新特性建模 3、对新语义建模 注解 &#xff08;note&#xff09;是附加在元素或元素集上用来表…

EcoVadis审核方法是什么符合EcoVadis规范的文件清单

EcoVadis审核方法是参照全球契约社会责任国际标准进行&#xff0c;包括环境、劳工及人权、商业道德、可持续采购等四大主题又分:能源消耗及温室气体排放、水环境管理、生态环境与物种多样性保护、局部环境污染、原材料及化学品使用(含废弃物)、产品使用、产品生命末期、消费者健…

控制应优先

先从大体上的去找规律&#xff0c;然后才是数字归纳&#xff08;更为详细的&#xff09;&#xff0c;同时控制关系应该优先&#xff08;这里是天数和位置&#xff09;。是否涉及所有对象不是广泛&#xff0c;如果是具体的数值就不是广泛。

天润融通携手好丽友,打造食品零售行业智能客服新标杆

AI大模型&#xff0c;如何给食品零售行业的客服服务带来质变&#xff1f; 在很多人印象中&#xff0c;食品零售行业是不需要客户服务的。 因为绝大多数食品都是通过经销商、零售商、商场这样的渠道进行销售。所以在食品零售行业&#xff0c;一直都有一句话&#xff0c;叫“渠…

贝加莱工控机维修5PC810.SX01-00 APC810系列

工控机维修常见故障:工控机无显示、自检不过、死机、触摸不灵、按键无法操作、与PLC通讯不上驱动器报过流过载、电压高、编码器错误 等。 PLC有输入无输出、报错等工控机维修常见故障现象 。 贝加莱工控机维修常见故障排查&#xff1a; 电源灯亮但工控机没有反应&#xff1a; …

ChatTTS:对话式文本转语音模型,开源啦!突破开源语音天花板...

最近&#xff0c;一个名为 ChatTTS 文本转语音项目爆火出圈&#xff0c;短短三天时间&#xff0c;在 GitHub 上已经斩获了 9.2 k 的 Star 量。 ChatTTS&#xff1a;对话式文本转语音模型 项目地址&#xff1a;https://github.com/2noise/ChatTTS/tree/main 体验地址&#xff1a…

Houdini pbd_constraints.h的文件位置

Houdini安装目录下的houdini\vex\include文件夹 C:\Program Files\Side Effects Software\Houdini 19.5.716\houdini\vex\include

Codeforces Round 950 (Div. 3)(A~E题解)

这场比赛我自己打的是真的垃圾&#xff0c;也是侥幸被拿下了&#xff0c;第三题当时没想清楚&#xff0c;要不然还能止损一下&#xff0c;惜败惜败 话不多说&#xff0c;现在来看A~E题的题解 A. Problem Generator 题解&#xff1a;这题水题一个&#xff0c;我们来考虑本题的…