重置内容可编辑的插入符位置

问题描述 投票:1回答:1

我目前正在尝试为Javascript创建语法突出显示工具,并且我目前面临的问题是创建这样的东西很常见,该问题是在用户键入或编辑时将插入标记的位置设置到最后contentEditable文本。

我在SO上研究并发现了this和许多其他解决方案,但没有一个有效。它会获得插入符号的位置,但永远不会重置它,因此我正在尝试寻找解决此问题的方法。

下面是我想出的代码。

html

<div id="editor" contentEditable="true" onkeyup="resetPosition(this)"></div>

<input type="text" onkeyup="resetPosition(this)" />

js

function getPos(e) {
    // for contentedit field
  if (e.isContentEditable) {
    e.focus()
    let _range = document.getSelection().getRangeAt(0)
    let range = _range.cloneRange()
    range.selectNodeContents(e)
    range.setEnd(_range.endContainer, _range.endOffset)

    return range.toString().length;
  }
  // for texterea/input element
  return e.target.selectionStart
}


function setPos(pos, e) {
  // for contentedit field
  if (e.isContentEditable) {
      e.focus()
      document.getSelection().collapse(e, pos);
      return
  }
  e.setSelectionRange(pos, pos)
}

function resetPosition(e) {
  if(e.isContentEditable) {
  let currentPosition = getPos(e);
  e.innerHTML=e.innerHTML.replace(/[0-9]/g, "a");
  setPos(currentPosition, e);

  return;
}

  e.value = e.value.replace(/[0-9]/g, "a");
  setPos(currentPosition, e);

}     

这对于文本输入很好,但对contentEditable divs无效。

[当我输入类似function的内容时,我得到otincfun

UPDATE:我可以通过将这一行从setPos更改为document.getSelection().collapse(e, pos);来修复document.getSelection().collapse(e.firstChild, pos);功能,但是出现了一个新的错误。

当我按ENTER键时,插入符号返回到第一行和第一个字符。请如何解决?


下面是小提琴链接

https://jsfiddle.net/oketega/bfeh9nm5/35/

谢谢。

javascript html caret
1个回答
0
投票

问题

[document.getSelection().collapse(element, index)将光标折叠到index指向的子节点,而不是字符索引。

我能够通过将此行从setPos更改为document.getSelection().collapse(e, pos);来修复document.getSelection().collapse(e.firstChild, pos);功能>

如果仅替换字符,则可以使用,但是如果要创建语法突出显示器,则需要将字符括在span元素中以设置样式。然后,e.firstChild只会将位置设置为e的第一个子对象内的索引,不包括后一个span

[另一件事是,您可能需要自动完成某些字符。在操作文本之前,插入符的位置可能与在操作之后的插入符位置不同。

解决方案

我建议创建一个<span id="caret-position"></span>元素以跟踪插入符号的位置。

它会像这样:

function textChanged(element) {
    // 1
    const text = setCursorMarker(element.innerText, element);

    // 2
    const html = manipulate(text);
    element.innerHTML = html;

    // 3
    const index = findCursorIndex(element);
    document.getSelection().collapse(element, index)
}

  1. 每次用户键入时,您都可以获取当前的插入符号位置并在其中的#caret-position元素中滑动。
  • 用突出显示的语法覆盖现有的html
  • 找出#caret-position在哪里,并将插入号放在那里。
  • 注意:当用户键入内容可编辑元素时,建议的监听方式是使用oninput监听器,而不是onkeyup。按住一个键可以插入许多字符。

    示例

    这里有一个有效的js小提琴:https://jsfiddle.net/Vehmloewff/0j8hzevm/latest/

    已知问题:两次按下Enter后,它将失去对插入符号应该位于的位置的跟踪。我不太确定为什么要这么做。

    热门问题
    推荐问题
    最新问题