无需移动光标即可将标签放在特定文本内 [英] Place tags around certain text within contenteditable without moving cursor

查看:152
本文介绍了无需移动光标即可将标签放在特定文本内的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on a simple (I thought) word processor. It uses contenteditable. I have a list of words that I want to always appear highlighted.

<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> 标签。事实证明这比我预期的要困难。

So basically what I need is a way to wrap a word in <span> tags. This has proven more difficult than I expected.

这是我先试过的:

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 方法这里

它完全符合我的需要,一个大问题:光标移动了。因为所有的文本都被替换了,光标就失去了它的位置,这对文本编辑器来说不是一件好事。

And it does exactly what I need it to do, with one big issue: the cursor gets moved. Because all the text is replaced, the cursor loses its place, which isn't a good thing for a text editor.

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

I've also tried a couple times using document.createRange, but the issue is that while given the start and end points of a range only includes visible characters, text.indexOf("highlight") gives the index including the tags and such.

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

A few ideas which I'm not sure how to execute:


  • 找出光标开始的位置,并在使用上面的代码后再将其放在那里

  • 找出<之间的索引差异 createRange indexOf

  • 也许已经有一个具有这种功能的库我找不到

  • Figure out where the cursor begins and place it there again after using the code above
  • Find the difference in indexes between createRange and indexOf
  • Maybe there's already a library with this kind of functionality that I just can't find

感谢您的帮助!

推荐答案

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

Firstly, I would recommend against doing this by manipulating innerHTML. It's inefficient and error-prone (think of the case where the content contains an element with a class of "highlight", for example). Here's an example of doing this using DOM methods to manipulate the text nodes directly:

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

维护插入位置可以通过多种方式实现。您可以使用基于字符偏移的方法,由于不考虑<$ c $隐含的换行符,因此存在一些缺点c>< br> 和块元素但相对简单。或者,您可以使用我的Rangy库的选择保存和恢复模块,根据您的需要可能有点过分,但可以使用相同的方法。

Maintaining the caret position can be achieved a number of ways. You could use a character offset-based approach, which has some disadvantages due to not considering line breaks implied by <br> and block elements but is relatively simple. Alternatively, you could use the selection save and restore module of my Rangy library, which may be overkill for your needs, but the same approach could be used.

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

Here is an example using the first approach:

http://jsbin.com/suwogaha/1

这篇关于无需移动光标即可将标签放在特定文本内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆