如何保存范围对象(来自 getSelection),以便我可以在不同的页面加载上重现它?

adr*_*nmc 6 html javascript jquery dom

我正在尝试制作一个网络应用程序,允许用户选择页面上的一些文本,然后单击另一个按钮突出显示它。当用户返回页面时,我希望突出显示也显示在同一位置。

所以我已经做到了:

var selectedRange = document.getSelection().getRangeAt(0);
highlightRange(selectedRange);
Run Code Online (Sandbox Code Playgroud)

其中highlightRange是一个突出显示范围的函数。到目前为止这有效。

问题是,我需要一种方法将 selectedRange 保存到数据库中,以便稍后可以再次获取它。之后,我需要根据该数据重新创建范围并再次突出显示它。我找到了这个方法:

document.createRange();
Run Code Online (Sandbox Code Playgroud)

从这里页面:https ://developer.mozilla.org/en-US/docs/Web/API/range

但我不太确定如何才能完成这项工作

更新:

我知道之后我需要从头开始重新创建范围。为此,我将使用这样的东西:

var range = document.createRange();

range.setStart(startNode,startOffset);
range.setEnd(endNode,endOffset);
Run Code Online (Sandbox Code Playgroud)

我可以轻松存储 startOffset 和 endOffset 因为这些只是数字。但startNode和endNode是节点对象。我不知道如何将其存储在数据库中?

更具体地说,我需要将对节点的引用存储在数据库中。

adr*_*nmc 5

我通过将范围中的 5 条信息保存到数据库中解决了这个问题:

var saveNode = range.startContainer;

var startOffset = range.startOffset;  // where the range starts
var endOffset = range.endOffset;      // where the range ends

var nodeData = saveNode.data;                       // the actual selected text
var nodeHTML = saveNode.parentElement.innerHTML;    // parent element innerHTML
var nodeTagName = saveNode.parentElement.tagName;   // parent element tag name
Run Code Online (Sandbox Code Playgroud)

然后为了从数据库构建范围,我有这个函数:

function buildRange(startOffset, endOffset, nodeData, nodeHTML, nodeTagName){
    var cDoc = document.getElementById('content-frame').contentDocument;
    var tagList = cDoc.getElementsByTagName(nodeTagName);
    
    // find the parent element with the same innerHTML
    for (var i = 0; i < tagList.length; i++) {
        if (tagList[i].innerHTML == nodeHTML) {
            var foundEle = tagList[i];
        }
    }

    // find the node within the element by comparing node data
    var nodeList = foundEle.childNodes;
    for (var i = 0; i < nodeList.length; i++) {
        if (nodeList[i].data == nodeData) {
            var foundNode = nodeList[i];
        }
    }

    // create the range
    var range = cDoc.createRange();

    range.setStart(startNode, startOffset);
    range.setEnd(endNode, endOffset);
    return range;
}
Run Code Online (Sandbox Code Playgroud)

从那里,我可以highlightRange再次使用我的函数来突出显示文本。

更新2022-01

不知道这个实际上还在使用。我想我不妨对这两个 for 循环以及我们如何使用现代语法改进它们给出两分钱:

const foundEle = tagList.find(x => x.innerHTML === nodeHTML);
const foundNode = nodeList.find(x => x.data === nodeData);
Run Code Online (Sandbox Code Playgroud)