更改 contenteditable 元素的 innerHTML 后,将插入符号放回原来的位置

Posted

技术标签:

【中文标题】更改 contenteditable 元素的 innerHTML 后,将插入符号放回原来的位置【英文标题】:Place caret back where it was after changing innerHTML of a contenteditable element 【发布时间】:2014-02-09 15:59:47 【问题描述】:

我需要在每次击键后在 javascript 中更新 contenteditable P 元素的 innerhtml

(没有 jQuery)

我不能使用输入或文本区域来代替 P 元素。

它工作正常,但是当 innerHTML 被重置时插入符号总是回到段落的开头。

我尝试使用其他关于插入符号和 contenteditable 的 SO 问题的解决方案,但在我的情况下似乎不起作用:我想将插入符号放回更新 innerHTML 之前的确切位置。

p.oninput=function()

  // Get caret position
  c = window.getSelection().
      getRangeAt(0).
      startOffset;
  console.log(c);

  // Update innerHTML
  p.innerHTML = p.innerHTML.toUpperCase();

  // Place caret back
  // ???
p border: 1px dotted red 
<p contenteditable id=p>type here

顺便说一句,它不需要在IE上工作,但如果你有跨浏览器的解决方案,我也会接受。

感谢您的帮助!

【问题讨论】:

在***.com/questions/1125292/…查看类似的答案 ***.com/a/13950376/96100 【参考方案1】:

考虑远离问题。

解决方案 1:在完成输入之前不要转换为大写。

解决方案 2:将 P 设置为等宽字体。使 P 透明。将 div 更新为大写的值。不确定如何显示插入符号...?

记得大约一年前看过一篇文章,其中编码界面使用类似的方法在文本区域中使用颜色编码。

【讨论】:

嗨,感谢这些想法,但是我的转换不仅仅是 toUpperCase。我为示例简化了它。我确实需要制作一种编码界面,但在 p(或 pre)元素内,而不是 textarea,我的问题只是插入符号的位置。 看看 codepen 和 jsfiddle 是怎么做的。并且有很多类似这个主题的 *** 答案。【参考方案2】:

我加了

const range = window.getSelection();
range.selectAllChildren(p);
range.collapseToEnd();

你的代码,它似乎解决了问题。

p.oninput=function()

  // Get caret position
  c = window.getSelection().
      getRangeAt(0).
      startOffset;
  console.log(c);

  // Update innerHTML
  p.innerHTML = p.innerHTML.toUpperCase();

  const range = window.getSelection();
  range.selectAllChildren(p);
  range.collapseToEnd();
p border: 1px dotted red 
<p contenteditable id=p>type here

【讨论】:

我已在您的答案中添加了代码 sn-p。请编辑它,这样我们才能真正看到你做了什么。 如果您在任何地方编辑文本而不是结尾,这不起作用

以上是关于更改 contenteditable 元素的 innerHTML 后,将插入符号放回原来的位置的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的angularjs指令中切换属性的值,如contenteditable?

将输入复选框的 DOM 属性更改反映到 innerHTML 属性

更改 innerHTML 后更改 contenteditable div 中的光标位置

当父元素是 contentEditable 时,是不是可以防止子元素被删除?

contenteditable元素的placeholder输入提示语设置

禁用 IE 中带有“contentEditable”标志的元素的自动 URL 检测