最近在我們的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}