记录一个需求,多行输入框 #变色输入话题,特殊符号,空格结束变色,且支持话题文字修改和删除,复制粘贴,限长500字,超出提示
js template div classbox p v-ifp classp请输入标题.../p div langzh-CN classdiv :contenteditablebox refeditor bluronBlur compositionstartonInput1(false) compositionendonInput1(true) inputonInput2(true) clickclick keyup.upgetData keyup.leftgetData keyup.rightgetData keyup.downgetData /div span classpos{{ string1.length }}/{{ textLength }}/span div classadd clickcar(#)# 添加话题/div /div /template script export default { name: RichText, data() { return { p: true, box: true, divspan: , string1: , // 内容 index: 0, // 光标位置 textLength: 500, // 文本的最大长度 list: [], // 内容中的关键词列表 kg: true, // 当前是否使用输入法输入 ischange: false, }; }, props: { value: { type:String, default: }, }, watch: { string1() { if (this.string1.length ! 0) { this.p false; } else { this.p true; } }, value: { handler: function (newValue, oldValue) { //判断赋值展示 this.$nextTick(() { const div this.$refs.editor; div.innerHTML newValue.videoName; this.onInput(true); }); }, deep: true, }, }, mounted() { this.getFocusPosition(); if (this.nameVideo?.videoName) { this.car(this.nameVideo.videoName); } }, methods: { // 使用上下左右按键在输入框中移动时需要获取光标的位置 getData(data) { this.index this.getFocusPosition(); }, // 每次点击div就重新获取一次当前光标的位置 click(a) { this.index this.getFocusPosition(); }, // 失去焦点触发传值,value是传进来的值 onBlur() { this.ischange true; this.uploadVideo.videoName this.string1; }, model() {}, // 使用delete按键删除 部分删减还没有全部实现还是出现跨标题的bug后续有空慢慢修复这个事件没啥用删除掉前面的bug就没了 handleDelete(event) { event.preventDefault(); const div this.$refs.editor; const text this.$refs.editor.innerText; const selection window.getSelection(); const selectedText selection.toString(); if (selectedText selectedText text) { div.innerHTML ; this.string1 ; this.index 0; this.onInput(true); return; } if (selectedText selectedText text) { div.innerHTML ; this.string1 ; this.index 0; this.onInput(true); return; } if (selectedText selectedText.indexOf(\n) -1) { let aa ; if ( this.index - selectedText.length this.index text.slice(this.index - selectedText.length, this.index) selectedText ) { aa text.slice(0, this.index - selectedText.length) text.slice(this.index); this.index this.index - selectedText.length; div.innerHTML aa; this.string1 this.$refs.editor.innerText; return this.onInput(true); } if ( this.index selectedText.length this.index text.slice(this.index, this.index selectedText.length) selectedText ) { aa text.slice(0, this.index) text.slice(this.index selectedText.length, text.length); div.innerHTML aa; this.string1 this.$refs.editor.innerText; return this.onInput(true); } div.innerHTML aa; this.string1 this.$refs.editor.innerText; this.onInput(true); return; } if (this.index 0) { const aa text.slice(0, this.index - 1) text.slice(this.index); div.innerHTML aa; this.string1 this.$refs.editor.innerText; this.index--; this.onInput(true); } }, //插入文本 car(zfc) { let le this.textLength - this.string1.length; if ((this.textLength this.string1.length this.string1.length 0) || le zfc.length) { this.$message({ type: error, message: 文字长度最大不超过500, }); return; } const index this.index; let arr this.string1.split(); arr.splice(index, 0, ...zfc.split()); const div this.$refs.editor; div.innerHTML arr.join(); this.index zfc.length; this.onInput(true, true); }, // 每次输入都会触发 onInput2(i) { const div this.$refs.editor; this.index this.getFocusPosition(); this.string1 this.$refs.editor.innerText; if (this.textLength this.string1.length this.string1.length 0 this.kg) { this.$message({ type: error, message: 文字长度最大不超过500, }); div.innerHTML this.string1.slice(0, this.textLength); div.blur(); } if (i this.kg) { this.onInput(i); } this.ischange true; this.uploadVideo.videoName this.string1; }, // 判断当前输入是否使用输入法 onInput1(e) { if (e) { this.kg true; if (this.textLength this.string1.length this.string1.length 0 this.kg) { const div this.$refs.editor; this.$message({ type: error, message: 文字长度最大不超过500, }); div.innerHTML this.string1.slice(0, this.textLength); div.blur(); } } else { this.kg false; } if (this.kg) { this.onInput(this.kg); } }, // 匹配关键词使用text替换e是否执行替换j暂时无用 onInput(e, j) { let text this.$refs.editor.innerText; this.string1 text; const re /#[^\s.,;?!。’、](?[\s.,;?!。’、])|#[^\s]/g; const newArr text.match(re); let matches newArr newArr.map((item) item.replace(/^#/, #)).sort((a, b) b.length - a.length); matches matches.forEach((item, i) { if (item #) { matches.splice(i, 1); } matches[i] item.slice(item.lastIndexOf(#), item.length); }); this.list matches; let div this.$refs.editor; if (matches e) { for (let i 0; i matches.length; i) { const match matches[i]; const regex new RegExp(${match}(?[\\s.,;?!。’、]|$)); text text.replace(regex, text classspan refspan$/text); div.innerHTML text; } } // 定位焦点光标 const range document.createRange(); const sel window.getSelection(); let index this.index; for (let i 0; i div.childNodes.length; i) { if (index div.childNodes[i].textContent.length) { index index - div.childNodes[i].textContent.length; } else { if (div.childNodes[i].className span) { range.setStart(div.childNodes[i].childNodes[0], index); } else { range.setStart(div.childNodes[i], index); } range.collapse(true); sel.removeAllRanges(); sel.addRange(range); return; } } }, // 获取光标位置 getFocusPosition() { const selection window.getSelection(); const range document.createRange(); selection.anchorNode range.setStart(selection.anchorNode, 0); const textNodes this.getTextNodes(this.$refs.editor); let index 0; // 遍历每一个文本节点 for (let i 0; i textNodes.length; i) { const textNode textNodes[i]; const length textNode.textContent.length; if (textNode selection.anchorNode) { index selection.anchorOffset; break; } index length; } return index; }, // 获取到每一个子节点 getTextNodes(node) { const textNodes []; if (node.nodeType Node.TEXT_NODE) { textNodes.push(node); } else { const children node.childNodes; for (let i 0; i children.length; i) { const child children[i]; textNodes.push(...this.getTextNodes(child)); } } return textNodes; }, } }; /script style .div { width: 580px; height: 115px; padding: 5px 15px; line-height: 16px; /* border: 1px #ccc transparent; */ overflow: auto; z-index: 999; border-radius: 4px; -webkit-user-modify: read-write-plaintext-only; } .div::-webkit-scrollbar { display: none; /* Chrome Safari */ } .p { position: absolute; top: 0px; left: 20px; color: #d3d1d1; z-index: -999999; } .span { color: #4f72f6; } .box { width: 600px; height: 106px; position: relative; padding-bottom: 40px; border: 1px #ccc solid; border-radius: 4px; } .pos { position: absolute; color: #ccc; bottom: 3px; right: 20px; } .colorred { color: #fe5353; } .add { width: 92px; margin-top: 25px; font-weight: 400; font-size: 14px; line-height: 24px; color: #4f72f6; background: #f0f3ff; border-radius: 4px; text-align: center; } .add:hover { background-color: #4f72f6; color: #f0f3ff; cursor: pointer; } /style

相关新闻

DS4Windows完整指南:5分钟让PS手柄在Windows上畅玩所有游戏

DS4Windows完整指南:5分钟让PS手柄在Windows上畅玩所有游戏

DS4Windows完整指南:5分钟让PS手柄在Windows上畅玩所有游戏 【免费下载链接】DS4Windows Like those other ds4tools, but sexier 项目地址: https://gitcode.com/gh_mirrors/ds/DS4Windows 还在为Windows游戏不兼容PlayStation手柄而烦恼吗?每次…

2026/8/6 17:49:38 阅读更多 →
相机位姿估计:PnP问题原理与工程实践

相机位姿估计:PnP问题原理与工程实践

1. 相机位姿估计的核心原理与应用场景在计算机视觉和机器人定位领域,相机位姿估计是一个基础但至关重要的技术。简单来说,就是通过图像信息计算出相机在三维空间中的位置和朝向。这个技术在我们日常生活中其实无处不在——从手机AR贴纸到自动驾驶车辆的定…

2026/8/6 17:49:38 阅读更多 →
微信小程序数据可视化终极指南:5分钟掌握echarts-for-weixin完整教程

微信小程序数据可视化终极指南:5分钟掌握echarts-for-weixin完整教程

微信小程序数据可视化终极指南:5分钟掌握echarts-for-weixin完整教程 【免费下载链接】echarts-for-weixin 基于 Apache ECharts 的微信小程序图表库 项目地址: https://gitcode.com/gh_mirrors/ec/echarts-for-weixin 还在为微信小程序中的数据展示而烦恼吗…

2026/8/6 17:48:38 阅读更多 →

最新新闻

UE5.5与MQTT实现JSON通信的实时交互方案

UE5.5与MQTT实现JSON通信的实时交互方案

1. 项目概述:UE 5.5与MQTT的JSON通信方案在实时交互应用开发中,Unreal Engine 5.5与MQTT协议的结合正在成为物联网、数字孪生等领域的标配方案。这个技术栈的核心价值在于:通过C实现的高性能MQTT客户端,能够以JSON格式在虚幻引擎中…

2026/8/6 19:48:30 阅读更多 →
autorestic vs resticprofile:两款主流Restic包装工具使用教程

autorestic vs resticprofile:两款主流Restic包装工具使用教程

autorestic vs resticprofile:两款主流Restic包装工具使用教程 【免费下载链接】awesome-restic Awesome Restic related projects 项目地址: https://gitcode.com/gh_mirrors/aw/awesome-restic Restic是一款功能强大的开源备份工具,但原生命令行…

2026/8/6 19:48:30 阅读更多 →
单片机计算机毕设之基于 STM32 单片机的阈值自定义智能园艺管理装置设计 基于 STM32 单片机的农业环境参数实时显示与自动控制系统(011702)

单片机计算机毕设之基于 STM32 单片机的阈值自定义智能园艺管理装置设计 基于 STM32 单片机的农业环境参数实时显示与自动控制系统(011702)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/8/6 19:48:30 阅读更多 →
Gartner 权威调研:超三成 CDO 陷入价值量化困局,数据战略该如何落地?

Gartner 权威调研:超三成 CDO 陷入价值量化困局,数据战略该如何落地?

当下,国内大中型企业已普遍设置 CDO/CDAO 岗位,大力建设数据中台,落地各类 AI 分析项目。但不少数据负责人都面临一个共同现实难题:难以量化数据与 AI 项目给业务带来的实际业务收益。Gartner 2025 面向全球 504 位数据高管的专项…

2026/8/6 19:48:30 阅读更多 →
重读CV系列——2、Fast-RCNN学习

重读CV系列——2、Fast-RCNN学习

1、详细工作流程步骤操作与R-CNN的差异1. 生成候选区域同样使用Selective Search,生成约2000个候选框。无变化,候选框生成依然独立。2. 整图特征提取将整张图片输入CNN,得到一张共享的、高分辨率的特征图(Feature Map)…

2026/8/6 19:48:30 阅读更多 →
N_m3u8DL-CLI-SimpleG:告别命令行,用可视化界面轻松驾驭M3U8视频下载

N_m3u8DL-CLI-SimpleG:告别命令行,用可视化界面轻松驾驭M3U8视频下载

N_m3u8DL-CLI-SimpleG:告别命令行,用可视化界面轻松驾驭M3U8视频下载 【免费下载链接】N_m3u8DL-CLI-SimpleG N_m3u8DL-CLIs simple GUI 项目地址: https://gitcode.com/gh_mirrors/nm3/N_m3u8DL-CLI-SimpleG 你是否曾经面对复杂的命令行参数感到…

2026/8/6 19:47:30 阅读更多 →

日新闻

深入解析LimboAI C++内核:架构设计与性能优化实战

深入解析LimboAI C++内核:架构设计与性能优化实战

1. 项目概述:为什么我们需要深入LimboAI的C内核?如果你是一名使用Godot引擎的游戏开发者,尤其是对AI行为逻辑有较高要求的项目,那么LimboAI这个名字你大概率不会陌生。它作为Godot 4生态中一个备受瞩目的行为树与状态机插件&#…

2026/8/6 0:00:06 阅读更多 →
Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

1. 项目概述与核心思路大家好,我是老张,一个在游戏开发一线摸爬滚打了十多年的老码农。今天咱们接着聊《空洞骑士》风格2D动作游戏的Demo制作。上一期我们搭好了基础框架,处理了角色移动和碰撞,这一期,我们要让游戏世界…

2026/8/6 0:00:06 阅读更多 →
被动防火门市场前景发展趋势

被动防火门市场前景发展趋势

被动防火门依靠材质结构、密闭构造阻隔烟火蔓延,无需电控启动,是建筑被动消防系统核心构件,行业依托新规管控、城市更新、工业安全升级迎来稳定扩容,整体朝着合规化、专项化、低碳化、智能化方向发展。现阶段 GB12955‑2024 新版国…

2026/8/6 0:00:06 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/5 15:00:43 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/5 13:13:56 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/5 10:20:36 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/5 23:28:39 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/5 21:00:14 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/5 23:46:51 阅读更多 →