繁体   English   中英

如何在 contenteditable div 中检测光标位置并在该位置插入文本

[英]How to detect cursor position in contenteditable div and insert text at that position

我正在使用咖啡脚本,我试图在内容可编辑的 div 中的光标位置插入文本。 我正在使用 Tim Dowan 函数来获取光标位置。 每次 div 光标位置中的类型发生变化但我不确定如何更新 updateTextArea 函数中的变量时,当我运行该函数时,我会得到相同的光标位置。 有没有更好的方法呢?

# Get curret position in Content Editable div
getSelectionCharacterOffsetWithin = (element) ->
  start = 0
  end = 0
  doc = element.ownerDocument or element.document
  win = doc.defaultView or doc.parentWindow
  sel = undefined
  if typeof win.getSelection != 'undefined'
    sel = win.getSelection()
    if sel.rangeCount > 0
      range = win.getSelection().getRangeAt(0)
      preCaretRange = range.cloneRange()
      preCaretRange.selectNodeContents element
      preCaretRange.setEnd range.startContainer, range.startOffset
      start = preCaretRange.toString().length
      preCaretRange.setEnd range.endContainer, range.endOffset
      end = preCaretRange.toString().length
  else if (sel = doc.selection) and sel.type != 'Control'
    textRange = sel.createRange()
    preCaretTextRange = doc.body.createTextRange()
    preCaretTextRange.moveToElementText element
    preCaretTextRange.setEndPoint 'EndToStart', textRange
    start = preCaretTextRange.text.length
    preCaretTextRange.setEndPoint 'EndToEnd', textRange
    end = preCaretTextRange.text.length
  {
    start: start
    end: end
  }

$(document).on 'input', '.reply-area', (e) ->
    currentElement = e.target

    reportSelection = (element) ->
      selOffsets = getSelectionCharacterOffsetWithin(element)
      return selOffsets.start

    currentCursorPosition = reportSelection(currentElement)

    updateTextArea = (element) ->
      # Get clicked user email
      thread_user_email = element.querySelector('.thread-user-email').textContent

      # Get element
      elementToInsert = $(currentElement).html()

      # Cursor position, email to insert, Text before cursor and text after cursor
      splitIndex = currentCursorPosition
      sliceIndex = currentCursorPosition - 1
      sliceString = elementToInsert.slice(sliceIndex, splitIndex)
      beforeString = elementToInsert.substring(0, sliceIndex)
      afterString = elementToInsert.substring(splitIndex)
      emailToInsert = '+' + thread_user_email + ' '     

      # Updated reply, comment text
      $(currentElement).html(beforeString + emailToInsert + afterString)

      # Hide the list
      $(thread_users_list).hide()

    $('.thread-users-list li').click (e) ->
        e.stopImmediatePropagation()
        updateTextArea(this)

虽然没有看到您尝试更改的 HTML 很难猜测,但我可以看到您的代码存在一些小问题。

在 CoffeeScript 中,函数的缩进很重要,因此您要确保所有内容都正确排列。 其次,您应该能够创建一个窗口级 var 来存储光标位置,然后您可以在代码中的任何位置访问该位置。 这是您在本地为我工作的代码的更新版本,并带有一些内联注释:

window.currentCursorPosition = null

# Get curret position in Content Editable div
getSelectionCharacterOffsetWithin = (element) ->
  ...
  ...

# You can simplify this quite a bit
$(document).on 'input', '.reply-area', (e) ->
  window.currentCursorPosition = getSelectionCharacterOffsetWithin(e.target).start

# Make sure this is not indented below $(document) code
updateTextArea = (element) ->
  ...
  ...

# Make sure this is not indented below $(document) code
$('.thread-users-list li').click (e) ->
    e.stopImmediatePropagation()
    updateTextArea(this)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM