Rangy:创造一个新的亮点是记住旧的亮点

时间:2013-02-06 17:01:21

标签: javascript rangy

我正在使用highlighter module in Rangy

我有一个div元素,它有一些html。 html实际上是使用ajax从文件加载的,我有一个按钮来执行此加载。

加载文本后,我可以选择显示的html的一部分并按下“突出显示”按钮。这会调用一些Rangy代码并根据需要突出显示文本......

//called on document load
rangy.init();
cssApplier = rangy.createCssClassApplier(highlightClassName, { normalize: true });
highlighter = rangy.createHighlighter(document, "TextRange");
highlighter.addClassApplier(cssApplier);

//called on "Highlight" button click
highlighter.highlightSelection(highlightClassName, selection);

为了复制,请选择大部分作为第一个高亮显示。

接下来,我点击我的加载html按钮重新加载html。正如预期的那样,亮点消失了。但现在我选择了另一段文字,这恰好与我做的第一个亮点重叠。现在,当我按下“突出显示”按钮时,出于某种原因突出显示的是前一个突出显示的突出显示。为什么会这样?

我知道必须与合并有关,但我不明白为什么。当我调试JS时,我可以看到选择(来自rangy.getSelection())是我期望的。

Here is a JSFiddle replication of the problem

2 个答案:

答案 0 :(得分:2)

我通过在每次highlightSelection调用之前重新创建荧光笔来解决此问题。我不知道为什么会这样,但是荧光笔必须存储一些关于用于高亮合并的先前高光的数据。

我的问题中的代码可以按如下方式更改以解决问题:

//called on document load
rangy.init();
cssApplier = rangy.createCssClassApplier(highlightClassName, { normalize: true });

//called on "Highlight" button click
highlighter = rangy.createHighlighter(document, "TextRange");
highlighter.addClassApplier(cssApplier);
highlighter.highlightSelection(highlightClassName, selection);

答案 1 :(得分:2)

之所以发生这种情况,是因为每个突出显示都是作为一对字符偏移存在,而不是在DOM中引用实际范围,这意味着当DOM的某些部分被替换时,现有的突出显示仍然没有意识到并继续假设它们适用于原始字符范围。

您的解决方法很好。另一种方法是调用荧光笔的removeHighlights()方法:

highlighter.removeHighlights(highlighter.highlights);

演示:http://jsfiddle.net/8pMEt/1/

我将添加一个removeAllHighlights()方法来做同样的事情。

文档没有说明的一件事是突出显示是为了处理静态DOM,或者至少是具有不会改变的文本内容的DOM。在创建高光之后更改DOM显然会抛弃角色偏移,整个过程都会崩溃。