如何保存范围对象(来自getSelection),以便在不同的页面加载上复制它?
How can I save a range object (from getSelection) so that I can reproduce it on a different page load?
我试图使一个web应用程序,允许用户选择一个页面上的一些文本,然后与另一个按钮的点击突出显示它。当用户返回页面时,我希望高亮显示也出现在相同的位置。
我已经写到了:
var selectedRange = document.getSelection().getRangeAt(0);
highlightRange(selectedRange);
其中highlightRange是一个突出显示范围的函数。
问题是,我需要一种方法来保存selecterange到数据库中,以便以后可以再次提取。之后,我需要从这些数据中重新创建范围并再次突出显示它。我找到了这个方法:
document.createRange();
本页链接:https://developer.mozilla.org/en-US/docs/Web/API/range
但是我真的不确定我怎么才能使这个工作
更新:
我知道之后我需要从头开始重新创建范围。要做到这一点,我将使用如下代码:
var range = document.createRange();
range.setStart(startNode,startOffset);
range.setEnd(endNode,endOffset);
我可以很容易地存储startOffset和endOffset,因为它们只是数字。但是startNode和endNode是节点对象。我不知道如何在数据库中存储这个?
更具体地说,我需要将引用存储到数据库中的节点
我通过从range中保存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
然后从数据库构建范围,我有这个函数:
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;
}
从那里,我可以再次使用我的highlightRange
函数来突出显示文本。
不知道这个实际上还在使用。我想我不妨就这两个for循环以及我们如何用现代语法改进它们给出两点意见:
const foundEle = tagList.find(x => x.innerHTML === nodeHTML);
const foundNode = nodeList.find(x => x.data === nodeData);
标题>当用户选择文本时运行以下脚本
let sel = window.getSelection();
let range = sel.getRangeAt(0);
let startNode = range.startContainer;
let endNode = range.endContainer;
if (startNode.nodeType == 3) {
var startIsText = true;
var startFlag = startNode.parentNode;
startNode = startNode.nodeValue;
} else {
var startIsText = false;
var startFlag = startNode;
}
if (endNode.nodeType == 3) {
var endIsText = true;
var endFlag = endNode.parentNode;
endNode = endNode.nodeValue;
} else {
var endIsText = false;
var endFlag = endNode;
}
let startOffset = range.startOffset;
let endOffset = range.endOffset;
let startTagName = startFlag.nodeName;
let startHTML = startFlag.innerHTML;
let endTagName = endFlag.nodeName;
let endHTML = endFlag.innerHTML;
//you can store this in database and use it
let rInfo = {
startNode: startNode,
startOffset: startOffset,
startIsText: startIsText,
startTagName: startTagName,
startHTML: startHTML,
endNode: endNode,
endOffset: endOffset,
endIsText: endIsText,
endTagName: endTagName,
endHTML: endHTML
};
window.localStorage.setItem("r", JSON.stringify(rInfo));
然后当用户返回页面
时使用以下脚本function findEle(tagName, innerHTML) {
let list = document.getElementsByTagName(tagName);
for (let i = 0; i < list.length; i++) {
if (list[i].innerHTML == innerHTML) {
return list[i];
}
}
}
function show(startNode,startIsText,startOffset,
endNode,endIsText,endOffset,sP,eP) {
var s, e;
if (startIsText) {
let childs = sP.childNodes;
console.log(childs);
for (let i = 0; i < childs.length; i++) {
console.log(childs[i].nodeValue);
console.log(startNode);
if (childs[i].nodeType == 3 && childs[i].nodeValue == startNode)
s = childs[i];
console.log(s);
}
} else {
s = startNode;
}
if (endIsText) {
let childs = eP.childNodes;
console.log(childs);
for (let i = 0; i < childs.length; i++) {
if (childs[i].nodeType == 3 && childs[i].nodeValue == endNode)
e = childs[i];
console.log(e);
}
} else {
e = endNode;
}
let range = document.createRange();
range.setStart(s, startOffset);
range.setEnd(e, endOffset);
let sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
function use(obj) {
let sP = findEle(obj.startTagName, obj.startHTML);
let eP = findEle(obj.endTagName, obj.endHTML);
show(
obj.startNode,
obj.startIsText,
obj.startOffset,
obj.endNode,
obj.endIsText,
obj.endOffset,
sP,
eP
);
}
let a = window.localStorage.getItem("r");
use(JSON.parse(a));
相关文章:
- 如何使用url加载程序在webpack中导入多个图像
- 如何在生成下载文件时显示加载动画
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 无法在通过jQuery的ajax加载的页面中执行javascript
- Emberjs应用程序加载在除Index之外的所有路由上
- 在chrome.tabs.onCreated之后加载HTML页面
- 单击F5时如何停止页面加载
- HTML5音频加载和播放获胜'我不能在iPad上工作
- 跟踪在页面加载时应用内联样式的JavaScript
- 在使用Polymer'加载所有json文件后执行方法;s的核心ajax
- jQuery Mobile pageinit在第一次加载页面上不起作用(可复制)
- 当我在 Javascript 中加载相同的声音 n 次时,浏览器会只是从服务器获取声音,然后将其复制到 n 个不同的对象
- 如何使用ZeroClipboard.js在页面加载时将静态单词复制到剪贴板
- 复制预加载的HTML/DOM方法会产生一个使用AJAX/PHP的数组
- javascript加载故障.代码可以使用手动复制粘贴,但不能使用JS
- 如何通过自定义上下文菜单将文本复制到剪贴板(不带flash/加载项)
- 点击Jquery后加载它,复制粘贴部分HTML
- 重新加载jQuery AJAX会复制JSON输出结果
- 如何保存范围对象(来自getSelection),以便在不同的页面加载上复制它?
- 热加载程序复制代码(n 次)而不是热插拔