javascript - 将标签放置在 contenteditable 内的某些文本周围,无需移动光标

标签 javascript html text contenteditable cursor-position

我正在开发一个简单的(我认为)文字处理器。它使用 contenteditable。我有一个单词列表,我希望这些单词始终突出显示。

<article contenteditable="true" class="content">
    <p>Once upon a time, there were a couple of paragraphs. Some things were <b>bold</b>, and other things were <i>italic.</i></p>
    <p>Then down here there was the word highlight. It should have a different color background.</p>
</article>

所以基本上我需要的是一种将单词包装在 <span> 中的方法标签。事实证明这比我预期的要困难。

这是我首先尝试的:

var text = document.querySelector('article.content').innerHTML
    start = text.indexOf("highlight"),
    end = start + "highlight".length;
text = text.splice(end, 0, "</span>");
text = text.splice(start, 0, "<span>");
document.querySelector('article.content').innerHTML = text;

它使用 splice找到方法here .

它确实做了我需要它做的事情,但有一个大问题:光标移动了。由于所有文本都被替换,光标会丢失其位置,这对于文本编辑器来说不是一件好事。

我也尝试过使用 document.createRange 几次,但问题是,虽然给定范围的起点和终点仅包含可见字符, text.indexOf("highlight")给出包括标签等的索引。

一些我不确定如何执行的想法:

  • 找出光标开始的位置,并在使用上面的代码后将其再次放置在那里
  • 查找 createRange 之间的索引差异和indexOf
  • 也许已经有一个具有此类功能的库,但我找不到

感谢您的帮助!

最佳答案

首先,我建议不要通过操纵 innerHTML 来执行此操作。它效率低下且容易出错(例如,考虑内容包含具有“突出显示”类的元素的情况)。下面是使用 DOM 方法直接操作文本节点的示例:

https://stackoverflow.com/a/10618517/96100

可以通过多种方式保持插入符位置。您可以使用 character offset-based approach ,由于不考虑 <br> 隐含的换行符,因此有一些缺点和 block 元素但是比较简单。或者,您可以使用 selection save and restore module我的 Rangy 库,这可能超出了您的需求,但可以使用相同的方法。

这是使用第一种方法的示例:

http://jsbin.com/suwogaha/1

关于javascript - 将标签放置在 contenteditable 内的某些文本周围,无需移动光标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24682716/

相关文章:

html - 报价的微数据

c++ - 如何交换文本文件中的行?

php - 如何在 PHP 中将 URL 变量传递给 javascript

javascript - React 中上下文发生变化时获取数据

javascript - 我的 Dijkstra 算法实现不返回最短路径

bash - 循环遍历 CSV 文件并在读取时创建新的 csv 文件?

android - 在 Android 中使用默认字体样式

带有警告的 PHP/Javascript session 超时

html - 如何在 Bootstrap 中将表单字段保持在同一行?

html - 如何继承父背景以使子列看起来长度相等