前言
主要介绍squire,wangeditor富文本编辑
以及用原生js 如何实现多个关键字标识
需求
如何标记多个关键字,取消关键字
第一种方法 原生 textarea 标记
准备资料参考:张鑫旭大大的博客 讲得非常的清楚哦
demo栗子:https://www.zhangxinxu.com/study/201104/range-miniblog-insert-topic.html
推荐文章:JS Range HTML文档/文字内容选中、库及应用介绍
知识点储备:range对象, getSelection MDN文档直通车
优点:原生实现的,不用额外引用第三方插件
缺点:功能稍微复杂一点 就难拓展了 全部自己写 花费的时间比较长
我的实践项目经验
痛点一:不可以插入<span style='color:red'></span> 标记三四个关键字是没有问题的,但是多个后 会标记的不准 计算的位置不准确。有尝试用正则匹配,但是解决的不理想(这里还是个人写的有问题)
思路:通过range 可以得到当前选中文字的位置,得到的文本加入标识(比如插入话题是#),选中的文字获取的位置包括插入的标识。之所以会导致位置计算不准<span>这个也是要记上的。
但是这个长度也是固定的 不应该存在计算位置准确(由于写法很久以前了 也没有留存)希望在座的各位不会出现这种情况
核心代码
funGetSelected(element){ // console.log(element.selectionStart, element.selectionEnd) //获取选中内容 if (!window.getSelection) { //IE浏览器 return document.selection.createRange().text; } else { return { selectedText: element.value.substr(element.selectionStart, element.selectionEnd - element.selectionStart), startPos: element.selectionStart, endPos: element.selectionEnd }; } },
funTextAsTopic(textObj, textFeildValue, flag){ textObj.focus(); if (textObj.createTextRange) { var caretPos = document.selection.createRange().duplicate(); document.selection.empty(); caretPos.text = textFeildValue; } else if (textObj.setSelectionRange) { var rangeStart = textObj.selectionStart; var rangeEnd = textObj.selectionEnd; var tempStr1 = textObj.value.substring(0, rangeStart); var tempStr2 = textObj.value.substring(rangeEnd); textObj.value = tempStr1 + textFeildValue + tempStr2; if(flag == 'delete'){ textObj.value = textObj.value.replace(`<${textFeildValue}>`, textFeildValue) } textObj.blur(); return textObj.value } },
第二种方法 富文本框squire
如果你不是用vue 也不是用react 或者ang 这个插件完全足够了
官网链接:http://neilj.github.io/Squire/
优点:超级轻量 很灵活(比我接下来要介绍的 wangeditor 要 灵活)
缺点:虽然我找到了npm 安装包 但是import失败 官网文档上没有看到写
也没有看到哪个筒子写了 如何引用成功(原生js 页面是完全可以的)
其他的 倒是没有体验太多
贴主要代码 这个我有一个完全写好的demo 有需要的可以私信我
$(function() { // 创建对象 const editor = new Squire(document.getElementById('demo')); //监听粘贴事件 editor.addEventListener('willPaste', function(data) { const content = $(data.fragment).text(); // 停止粘贴 data.preventDefault(); // 转换成text添加到富文本 editor.insertHTML(content); }); // 按钮事件 $('#btn').on('click', function() { if (editor.getSelectedText().length == 0) { return; } if ($(editor.getSelection().commonAncestorContainer.parentNode).hasClass('colour')) { editor.setTextColour('') return; } // 将选中的文字设置成红色 editor.setTextColour('red'); //editor.insertHTML(`<span style="color: red;"><${editor.getSelectedText()}></span>`); // 聚合 const content = editor.getHTML().replace(/</span><span class="colour" style="color:red">/g, ''); editor.setHTML(content); }); // 关键字事件 $('#demo').on('click', '.colour', function() { alert('这是一个关键字点击事件,当前关键字是: '+$(this).text()); }); //$('#demo').on('mouseenter', '.colour', function() { //alert('这是一个关键字悬浮事件,当前关键字是: '+$(this).text()); //}); });
怎么引用都不会成功 由于我们的项目主要用的vue 框架(如果一定要用的话 应该要自己封装一层)
第三种方法富文本编辑 wangeditor
第二个框架的是完全满足我们的需求了,但是我自己懒得再去封装怎么在vue里面引用成功
有专门的学习手册:https://www.kancloud.cn/wangfupeng/wangeditor3/404586
源码开源:https://github.com/wangfupeng1988/wangEditor
优点:满足基本的富文本编辑,有专门的文档,还在维护
缺点:不可以自定义工具栏 方法没有这么灵活 需要变通一下才可以实现某些功能
我的实战项目经验
可以获取当前选中文本,可以取消标记,可以获取当前焦点最近的关键字。
核心主要代码
import E from 'wangeditor' //引用 var editor = new E(this.$refs.editor) editor.customConfig.onchange = (html) => { this.editorContent = editor.selection.getSelectionText() console.log(editor.selection.getSelectionText()) } editor.customConfig.menus = [ //配置菜单 'foreColor' ] editor.customConfig.colors = [ //配置颜色 'red','#000' ] editor.customConfig.onfocus = function () { } editor.create() document.getElementById('btn2').addEventListener('click', function () { // 读取 text let key = editor.selection.getSelectionText() //获取选中内容 }, false) document.getElementById('btn1').addEventListener('click', function () { //取消标记 let test = editor.selection.getSelectionStartElem()[0].style.color if(test == 'red'){ editor.selection.getSelectionStartElem()[0].style.color = '#000' } }, false) $('#editor').on('click', function() { //获取最近关键字 let texts = editor.selection.getSelectionStartElem()[0].innerText });
fannie式总结
延伸思考 就是有很多中标记 这个标记的内容 都要对应储存 不同颜色区分 可以取消标记这些之类的
还有web用富文本有一点点安全性问题哦