react中ant-design组件实现textarea获取光标位置并插入表情图片
最近在我们的service后台做了个实时聊天的需求,类似于微信网页版,里面有个输入框,在输入框里面可插入表情,调研了一下发现微信的表情一部分是微信自带的表情,还有一部分是emoji表情,需求没有那么多要求,只支持emoji表情即可,总结一下这个小功能,还挺有意思的
在这里不总结聊天输入框了,因为还适用到了websocket,代码比较多,在这里分享一下一个类似的小功能,类似于编辑话术
先放一个小demo的图片:
这个小功能很简单,比较麻烦的是获取光标的位置,在这里就只是介绍一下获取光标的位置的方法吧
首先是使用antd的TextArea组件,使用ref获取当前的dom:
<TextArea ref={(input) => this.contentProp = input} onChange={(e) => this.changeTextArea(e, id, index)} placeholder="请输入" style={{ width:'600px' }} maxLength="200" />
然后就是获取光标的位置的函数:
getPositionForTextArea=(ctrl)=> { // 获取光标位置 let CaretPos = { start: 0, end: 0 }; if (ctrl.selectionStart) {// Firefox support CaretPos.start = ctrl.selectionStart; } if(ctrl.selectionEnd) { CaretPos.end = ctrl.selectionEnd; } return (CaretPos); }; setCursorPosition =(ctrl, pos)=> { ctrl.focus(); ctrl.setSelectionRange(pos, pos); };
最后在使用的地方调用一下:
let props = this.contentProp.textAreaRef; // 获取dom节点实例 let position = this.getPositionForTextArea(props); // 光标的位置 let length = content.length; // setFieldsValue方法是异步的 // 不加延时器就会发生光标还没插入文字呢 就已经把光标插入后的位置提前定位 setTimeout(()=>{ this.setCursorPosition(props, position.start + length); },20);
// 当然,如果是使用setstate改变输入框内容在回调里改变光标位置就不会出现这种问题
this.setState({text}, () => this.setCursorPosition(props, poi.start + length));
以上就是获取光标位置并插入内容的代码,
由于我是遍历出现多个textarea,所以在使用的时候,获取dom节点加了个index
ref={(input) => this.contentProps[index] = input}