在 rangy 中创建荧光笔时使用文档以外的任何其他元素

Using any other element than document while creating the highlighter in rangy

我正在使用 highlighter module of rangy 突出显示 HTML 页面的特定部分。特定的 div 将仅使用实际上是 angular 指令的模块。我在后端保留高亮范围,并在再次加载页面时再次渲染它。这是因为我要坚持亮点。 我面临的问题是该页面几乎没有动态组件,这些组件可能会在每次页面加载时发生变化,也可能不会发生变化。这会在渲染保存的高光时产生问题。 为了解决这个问题,我尝试在创建荧光笔时使用静态元素,使用以下代码

var highlighter = rangy.createHighlighter(element);

这给了我以下错误 -

TypeError: Failed to execute 'setStart' on 'Range': parameter 1 is not of type 'Node'.
    at WrappedRange.api.createCoreModule.rangeProto.setStart (allPluginJsPartTwo.js:42934)
    at WrappedRange.moveToBookmark (allPluginJsPartTwo.js:42427)
    at Object.characterRangeToRange (allPluginJsPartTwo.js:45712)
    at Highlight.getRange (allPluginJsPartTwo.js:45816)
    at Highlight.apply (allPluginJsPartTwo.js:45837)
    at Highlighter.deserialize (allPluginJsPartTwo.js:46203)
    at allCommonJs.js:11098
    at processQueue (allFrameworkJs.js:14804)
    at allFrameworkJs.js:14820
    at Scope.$eval (allFrameworkJs.js:16064)

(请忽略JS文件名和代码行,由grunt合并。) 错误来了,因为特定的 containerNode 未定义。这里基本上缺少的 containerNode 被定义为 element.body,它对于除文档元素之外的任何 DOM 元素都是未定义的。
我尝试使用以下愚蠢的解决方法。

element.body = document.body;

这与在 createHighlighter() 中发送文档对象完全相同。

所以我假设 rangy.createHighlighter() 只需要将文档对象作为参数。我的问题是,如何让它适用于任何元素,而不仅仅是文档对象?

Rangy 不支持确切的要求,但是,我不得不创建一个不那么复杂的单独函数,我不确定为什么 Rangy 没有内置它。

但无论如何,我是这样做的。 Rangy 使用字符范围序列化和反序列化突出显示的内容。所以我在将范围保存到包含我关注的静态 HTML 的 div 之前对范围进行了归一化。

例如,如果 div 的 id 为 page-container,我得到了字符范围直到那个,并在保存之前和我想反序列化时从突出显示的范围中减去该部分亮点,我只是再次计算了偏移量并将其添加回标准化范围并且它像魔术一样工作:-D

这是计算偏移量的代码 -

function getRangeOffset(){
    var converter = highlighter.converter;
    var pageContainer = document.getElementById('page-container');
    var containerRange = rangy.createRange(document);
    containerRange.setStart(pageContainer,0);
    var containerCharRange = converter.rangeToCharacterRange(containerRange);
    var rangeOffset = containerCharRange.start;
    return parseInt(rangeOffset);
}