| 
                         不管是粘贴文本也好,还是图片也好,我们的输入框始终是处于聚焦(focus)状态。而当我们从表情面板里选择 emoji 表情的时候,输入框会先失焦(blur),然后再重新聚焦。由于 document.execCommand 方法必须在输入框聚焦状态下才能触发,所以对于处理 emoji 插入来说就无法使用了。 
上一小节讲过,Selection 可以让我们拿到聚焦状态下所选文本的起点位置 startOffset 和终点位置 endOffset,如果没有选择文本而仅仅处于聚焦状态,那么这两个位置的值相等(相当于选择文本为空),也就是光标的位置。只要我们能够在失焦前记录下这个位置,那么就能够通过 range 把 emoji 插入正确的地方了。 
首先编写两个工具方法。新建一个 cursorPosition.js 文件: 
- /**  
 -  * 获取光标位置  
 -  * @param {DOMElement} element 输入框的dom节点  
 -  * @return {Number} 光标位置  
 -  */  
 - export const getCursorPosition = (element) => {  
 -   let caretOffset = 0  
 -   const doc = element.ownerDocument || element.document  
 -   const win = doc.defaultView || doc.parentWindow  
 -   const sel = win.getSelection()  
 -   if (sel.rangeCount > 0) {  
 -     const range = win.getSelection().getRangeAt(0)  
 -     const preCaretRange = range.cloneRange()  
 -     preCaretRange.selectNodeContents(element)  
 -     preCaretRange.setEnd(range.endContainer, range.endOffset)  
 -     caretOffset = preCaretRange.toString().length  
 -   }  
 -   return caretOffset  
 - }  
 - /**  
 -  * 设置光标位置  
 -  * @param {DOMElement} element 输入框的dom节点  
 -  * @param {Number} cursorPosition 光标位置的值  
 -  */  
 - export const setCursorPosition = (element, cursorPosition) => {  
 -   const range = document.createRange()  
 -   range.setStart(element.firstChild, cursorPosition)  
 -   range.setEnd(element.firstChild, cursorPosition)  
 -   const sel = window.getSelection()  
 -   sel.removeAllRanges()  
 -   sel.addRange(range)  
 - } 
 
  
有了这两个方法以后,就可以放入 editor 节点里面使用了。首先在节点的 keyup 和 click 事件里记录光标位置: 
- let cursorPosition = 0  
 - const editor = document.querySelector('.editor')  
 - editor.addEventListener('click', async (e) => {  
 -   cursorPosition = getCursorPosition(editor)  
 - })  
 - editor.addEventListener('keyup', async (e) => {  
 -   cursorPosition = getCursorPosition(editor)  
 - }) 
 
                          (编辑:泰州站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |