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

标签 javascript html caret

我目前正在尝试为 创建语法荧光笔。 Javascript 我目前面临的问题是我发现创建类似这样的东西很常见,即在用户键入或编辑 contentEditable 文本时将插入符号位置设置到末尾。

我研究发现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 .

更新:我能够修复 setPos通过从 document.getSelection().collapse(e, pos); 更改此行来运行至document.getSelection().collapse(e.firstChild, pos);但是出现了一个新的错误。

When I press ENTER Key, the caret goes back to the first line and first character. Please how do I fix?



下面是 fiddle 链接

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

谢谢。

最佳答案

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

I was able to fix the setPos function by changing this line from document.getSelection().collapse(e, pos); to document.getSelection().collapse(e.firstChild, pos);



如果您只是替换字符,这将起作用,但如果您正在创建语法荧光笔,则需要将字符包含在 span 中。元素来设置它们的样式。 e.firstChild然后只会将位置设置为 e 内的索引的第一个 child ,不包括后者 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)
}

  • 每次用户键入时,您都可以获得当前插入符号的位置并滑入#caret-position里面的元素。
  • 用语法高亮文本覆盖现有的 html
  • 找出#caret-position是并将插入符号放在那里。

  • Note: The recommended way to listen for when the user types in the content-editable element is with the oninput listener, not onkeyup. It is possible to insert many characters by holding down a key.



    例子

    这里有一个有效的 js fiddle:https://jsfiddle.net/Vehmloewff/0j8hzevm/132/

    已知问题:点击 Enter 后两次,它丢失了插入符号的位置。我不太确定它为什么会这样做。

    关于javascript - 重置内容可编辑的插入符号位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61155285/

    相关文章:

    javascript - 如何从用户代理字符串(4.x 版本)中找出 Android 设备

    javascript - 我的 javascript onclick 和 onmouseover 有什么问题?

    javascript - 目标 ="_blank"在 IOS 中不工作

    keyboard-shortcuts - 使用 Karabiner-Elements 将应用程序键映射到插入符位置的右键单击

    jquery - 如何在文本上使用 TinyMCE 函数而不实际选择该文本?

    javascript - 无法让 javascript 加载 .txt 文件来加载链接

    javascript - 在 Webpack 插件中插入函数

    html - 可以设置 iFrame 的 src 图像的宽度吗?

    javascript - 如何在 contenteditable div 中聚焦于 <p>

    javascript - 查看特定日期是星期几