最近有个需求就是做一个类似聊天输入框的功能,要求可以插入emjoy表情图的这种。
样式不好看请忽略,大概就是这样。
讲一下主要思路吧,嫌麻烦的可以往下拉 看代码
首先这里 输入框肯定是不能使用 textarea这种,而是选择的用div模拟一个输入框 也就是设置contenteditable="true" 这个属性就可以让用户进行编辑
进入页面的时候要让这个 “输入框获取到焦点” 也就是在mounted 阶段 获取到这个元素使用.focus的方法
<div ref="contentValue" class="footerContent" contenteditable="true"></div> //这是输入框
this.$refs.contentValue.focus(); //聊天框初始获取焦点
这个时候就可以进行编辑等操作了,但是还有一个比较重要的问题是记录焦点位置。
当你的鼠标进行点击的时候,当前输入框会失去焦点。或者你点击文本中间想插入其他表情图的时候该怎么去判断 往哪里去插入
首先要给你的输入框绑定一个事件 在这个事件里面去拿到当前焦点
var sel = getSelection().getRangeAt(0); this.select = sel;
然后再点击表情的时候
var sel = window.getSelection();//获取当前焦点 if (this.select) {//判断有没有存起来的光标位置 sel.removeAllRanges();//删除当前光标位置 sel.addRange(this.select);//把存起来的光标位置赋值上去 } var frag; var range = sel.getRangeAt(0)//拿到光标位置 if (range.createContextualFragment) { // eslint-disable-next-line no-undef frag = range.createContextualFragment(data);//data是需要渲染的表情图片 } else { var el = document.createElement("div"); //创建容器 el.innerHTML = data;//将表情图/文字进行赋值 (frag = document.createDocumentFragment()), node, // eslint-disable-next-line no-undef lastNode; while ((node = el.firstChild)) { // eslint-disable-next-line no-undef lastNode = frag.appendChild(node); } } var node = frag.lastChild; range.insertNode(frag);//挂载节点 range.setStartAfter(node); sel.removeAllRanges();//用完别忘记了清 sel.addRange(range);
原文地址 segmentfault.com/a/119000001… 作者挺厉害