位置: IT常识 - 正文

富文本实现@选择人(富文本功能)

编辑:rootadmin
准备工作 npm i wangeditor --save npm i caret-pos --save 组件: <!--富文本--> <div :id="editorEleId" @keydown="onKeyDownInput($event)" @click="onClickEditor" ></ ...

推荐整理分享富文本实现@选择人(富文本功能),希望有所帮助,仅作参考,欢迎阅读内容。

富文本实现@选择人(富文本功能)

文章相关热门搜索词:富文本怎么用,富文本js,富文本js,实现富文本编辑器,富文本使用,富文本类型,实现富文本编辑器,实现富文本编辑器,内容如对您有帮助,希望把文章链接给更多的朋友!

准备工作

npm i wangeditor --savenpm i caret-pos --save

组件:

<!--富文本--><div :id="editorEleId" @keydown="onKeyDownInput($event)" @click="onClickEditor"></div><!-- 成员选择 --> <div class="userPopupList" :style="{left: left + 'px', top: top + 'px'}" v-show="show"> <el-input v-model="userName" ref="input"></el-input> <ul> <li v-for="user in protectPersons.filter((item) => item.workNick.includes(this.userName))" :key="user.userId" @click="createSelectElement(user.workNick,user.userId)" > <el-avatar :size="22" :src="user.icon" class="m-r-10" style="vertical-align: middle" > <img src="../../assets/images/defaultIcon.gif"/> </el-avatar> <span>{{user.workNick}}</span> </li> </ul></div>.userPopupList{ position: fixed; z-index: 9999; /deep/input{ border:none; background: transparent; } ul{ max-height: 200px; overflow-y: auto; border: 1px solid #dbdada; background: #fff; padding: 10px 10px 0; border-radius: 3px; li{ margin-bottom: 5px; padding: 5px 10px; &:hover{ background: #f6f5f5; } } }}position:any = {};left:number = 0;top:number = 0;show:boolean = false;isRendering: boolean = false;userName: string = '';users:any = []; ...富文本初始化this.editor.config.onchange = () => { // 生成@的标签的时候会触发渲染、此时不要记录光标坐标 if (this.isRendering === false) { this.setRecordCoordinates() // 记录坐标 }else { this.isRendering = false; }};// 每次点击获取更新坐标onClickEditor() { this.setRecordCoordinates()}// 获取当前光标坐标setRecordCoordinates() { try { // getSelection() 返回一个 Selection 对象,表示用户选择的文本范围或光标的当前位置。      if(!this.show){       const selection:any = window.getSelection();       this.position = {       range: selection.getRangeAt(0),       selection: selection       }      } } catch (error) { console.log(error, '光标获取失败了~') }}// keydown触发事件 记录光标onKeyDownInput(e:any) { const isCode = ((e.keyCode === 229 && e.key === '@') || (e.keyCode === 229 && e.code === 'Digit2') || e.keyCode === 50) && e.shiftKey if (isCode) { this.setRecordCoordinates(); // 保存坐标 this.getPosition(); // 显示选择框,定时原因:1、@会插入到input中,2、光标位置也是input的,会导致插入位置错误 setTimeout(()=>{ this.show = true this.$nextTick(()=>{ (this.$refs.input as any).focus(); }) },200) }}//弹窗列表 - 选人 - 生成@的内容createSelectElement(name:string, id:string, type = 'default') { // 获取当前文本光标的位置。 const { range } = this.position // 生成需要显示的内容 let spanNodeFirst:any = document.createElement('span') spanNodeFirst.className = 'user-node' spanNodeFirst.style.color = '#409EFF' spanNodeFirst.innerHTML = `@${name}&nbsp;` // @的文本信息 spanNodeFirst.dataset.id = id // 用户ID、为后续解析富文本提供 spanNodeFirst.contentEditable = false // 当设置为false时,富文本会把成功文本视为一个节点。 // 需要在字符前插入一个空格否则、在换行与两个@标签连续的时候导致无法删除标签 let spanNode = document.createElement('span'); spanNode.innerHTML = '&nbsp;'; //创建一个新的空白的文档片段,拆入对应文本内容 let frag = document.createDocumentFragment() frag.appendChild(spanNode); frag.appendChild(spanNodeFirst); frag.appendChild(spanNode); // 如果是键盘触发的默认删除面前的@,前文中我们没有阻止@的生成所以要删除@的再插入ps:如果你是数组遍历的请传入type 不然会一直删除你前面的字符。 if (type === 'default') { const textNode = range.startContainer; range.setStart(textNode, range.endOffset - 1); range.setEnd(textNode, range.endOffset); range.deleteContents(); } this.isRendering = true; // 判断是否有文本、是否有坐标 if ((this.editor.txt.text() || type === 'default')&& this.position && range) { range.insertNode(frag) } else { // 如果没有内容一开始就插入数据特别处理 this.editor.txt.append(`<span data-id="${id}" contentEditable="false">@${name}&nbsp;</span>`) } this.show = false; this.userName = '';}// 获取当前光标位置getPosition () { const ele:any = this.editor.$textElem.elems[0]; const pos = position(ele) const off = offset(ele) const parentW = ele.offsetWidth // 这个是弹窗列表 const childEle:any = document.getElementsByClassName("userPopupList") const childW = childEle.offsetWidth // 弹框偏移超出父元素的宽高 if (parentW - pos.left < childW) { this.left = off.left - childW } else { this.left = off.left } this.top = off.top - 4}//提交评论sure(ev: any) { ... const users = document.querySelectorAll('.user-node'); let userIds:string[] = []; users.forEach((item:any) => { userIds.push(item.getAttribute('data-id')) }) ...}
本文链接地址:https://www.jiuchutong.com/zhishi/310445.html 转载请保留说明!

上一篇:Python如何实现时间累加的计算器(python @time)

下一篇:python如何查看hdf5文件(Python如何查看中风患者两表的数据量)

  • 麒麟990比麒麟980提升了吗(麒麟990比麒麟980性能提升多少)

    麒麟990比麒麟980提升了吗(麒麟990比麒麟980性能提升多少)

  • 只显示对方更新了说说(对方显示更新了说说是什么意思)

    只显示对方更新了说说(对方显示更新了说说是什么意思)

  • 华为nova6充电速度(华为nova6充电速度慢)

    华为nova6充电速度(华为nova6充电速度慢)

  • 为什么找不到撤销退款(为什么找不到撤销退货退款申请)

    为什么找不到撤销退款(为什么找不到撤销退货退款申请)

  • 京东7天无理由退货运费谁出(京东7天无理由退货钱多久到账)

    京东7天无理由退货运费谁出(京东7天无理由退货钱多久到账)

  • 用于设置页面元信息的是(用于设置页面元信息的标记是)

    用于设置页面元信息的是(用于设置页面元信息的标记是)

  • 电脑屏幕显示不全有黑边怎么办(电脑屏幕显示不完整不满屏)

    电脑屏幕显示不全有黑边怎么办(电脑屏幕显示不完整不满屏)

  • g03指令是什么意思(g02g03指令是什么意思)

    g03指令是什么意思(g02g03指令是什么意思)

  • 闲鱼小法庭卖家胜利钱多久到账(闲鱼小法庭卖家赢了后怎么处理)

    闲鱼小法庭卖家胜利钱多久到账(闲鱼小法庭卖家赢了后怎么处理)

  • 比心注销了还能注册吗(比心注销账号后个人信息会泄露吗)

    比心注销了还能注册吗(比心注销账号后个人信息会泄露吗)

  • qq群视频人数有限制吗(qq群聊视频最多几人)

    qq群视频人数有限制吗(qq群聊视频最多几人)

  • 微信步数可以看什么时候走的吗(微信步数可以看到之前的 但是今天0)

    微信步数可以看什么时候走的吗(微信步数可以看到之前的 但是今天0)

  • 抖音主页访问人数是什么意思(抖音的主页访问)

    抖音主页访问人数是什么意思(抖音的主页访问)

  • 文件中转站空间不足(文件中转站空间不足删除对方能不能收到)

    文件中转站空间不足(文件中转站空间不足删除对方能不能收到)

  • iphone11电池多少毫安(Iphone11电池多少需要换)

    iphone11电池多少毫安(Iphone11电池多少需要换)

  • 网络电视可以看春晚吗(网络电视可以看手机却连不上网络)

    网络电视可以看春晚吗(网络电视可以看手机却连不上网络)

  • 照片大小怎么改到2m(照片大小怎么改到10k)

    照片大小怎么改到2m(照片大小怎么改到10k)

  • 手机qq能发多大的视频(手机qq能发大文件吗)

    手机qq能发多大的视频(手机qq能发大文件吗)

  • 怎样知道微信对方已读(怎样知道微信对方有没有删除自己)

    怎样知道微信对方已读(怎样知道微信对方有没有删除自己)

  • 小米8怎么设置未知来源(小米8怎么设置屏幕常亮)

    小米8怎么设置未知来源(小米8怎么设置屏幕常亮)

  • usb设计灵感是什么(usb设计规范)

    usb设计灵感是什么(usb设计规范)

  • 美颜相机背景虚化在哪(美颜相机背景虚化怎么取消)

    美颜相机背景虚化在哪(美颜相机背景虚化怎么取消)

  • 苹果8p声音小怎么办(苹果8p声音怎么调大)

    苹果8p声音小怎么办(苹果8p声音怎么调大)

  • 苹果x能插两个卡吗(苹果x能插两个电信卡吗)

    苹果x能插两个卡吗(苹果x能插两个电信卡吗)

  • 苹果xs是双卡的吗(iphone xs是不是双卡)

    苹果xs是双卡的吗(iphone xs是不是双卡)

  • j1900性能(J1900性能怎么样)

    j1900性能(J1900性能怎么样)

  • 多数路由器的ip地址和网关192.168.1.1(路由器ip分配数量)

    多数路由器的ip地址和网关192.168.1.1(路由器ip分配数量)

  • Windows 7系统如何创建硬盘分区?(win7系统咋样)

    Windows 7系统如何创建硬盘分区?(win7系统咋样)

  • 有反爬机制就爬不了吗?那是你还不知道反反爬,道高一尺魔高一丈啊(常见反爬策略)

    有反爬机制就爬不了吗?那是你还不知道反反爬,道高一尺魔高一丈啊(常见反爬策略)

  • 哪些产品享受教育优惠
  • 城建税多少会减免
  • 缴个人所得税分录怎么写
  • 烟叶税税率计算方法
  • 网上申领发票收到后需要怎么操作
  • 怎么根据实发工资算应发工资
  • 建筑行业预缴增值税可以用进项抵缴吗
  • 计提所得税是在结转损益之前还是之后
  • 个体户认定一般纳税人
  • 离境退税政策文件
  • 增值税专用发票的税率是多少啊
  • 应收票据主要包括
  • 附加税按实际缴纳计提吗
  • 销售自产自销的产品要交税吗?
  • 购买车间用的材料怎么做分录
  • 非经营活动界定,主要说明哪些情形不交增值税
  • 双薪制工资如何缴纳个人所得税?
  • 关于现代服务业的书籍
  • 小规模季度超过30万怎么填报增值税
  • 集团内部股权无偿划转引起资本公积增加需要印花税
  • 生产企业先出库后入库
  • 社保公积金外包对员工的利弊
  • 会计制度备案成本核算方法一般选择哪个
  • u盘怎么安装软件
  • 长期待摊会计分录
  • windows无法配置用户文件
  • 运城盐湖中国死海养生城
  • 购买办公楼之后怎么入账
  • 发放职工薪酬账务怎么做
  • 自行建造厂房如何缴税
  • 图书发票怎么开
  • 编程主要学什么东西
  • 小程序的生命周期函数有哪些
  • css圆角边框弧度代码
  • 应征增值税不含税销售额(5%征收率)是什么意思
  • 命令启动服务管理
  • 研发费用加计扣除的条件
  • 会计损益类科目核算
  • 用友固定资产模块反结账
  • 小规模纳税人每月不超过10万
  • 织梦如何开启会员功能
  • 货物不符合质量条款规定
  • 审计外聘人员支付标准
  • 限定性净资产是资产类科目吗
  • 有关预收款的说法
  • 材料采购的账务怎么处理
  • 原始凭证审核要点包括
  • 财务软件是有哪些软件
  • 欠供应商货款会坐牢吗
  • 运费不支付会怎么样
  • 个人应如何进行社会实践
  • 零申报报表怎么填写
  • 预付账款未取得发票
  • 管理费用和营业费用的比例
  • 公司装修费用如何计算
  • 公司注销项目怎么办
  • 行政拨付工会经费可以用于职工福利发放吗
  • 固定资产报废如何记账
  • 固定资产应计入什么账户
  • 招待费汇算清缴一定要调整的吗
  • 如何计提当期费用成本
  • 非营利医疗机构是什么单位
  • mysql数据加解密
  • ubuntu的系统设置在哪里
  • iis设置mime
  • win8激活失败
  • win7如何运行命令
  • win8系统怎么设置开机密码
  • vim如何复制粘贴
  • 笔记本怎么设置定时关机
  • 冗余文件是什么意思
  • 方块滚动代码怎么写
  • 安卓基础入门教程
  • scrapy—redis
  • JavaScript window.document的属性、方法和事件小结
  • js复制对象的方法有哪几种
  • js原型使用场景
  • JavaScript 入门·JavaScript 具有全范围的运算符
  • vs开发unity教程
  • 一般纳税人简易征收会计分录
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设