gpt4 book ai didi

javascript - 保存选择文本并稍后在 html 和 javascript 中显示

转载 作者:技术小花猫 更新时间:2023-10-29 12:08:08 25 4
gpt4 key购买 nike

我在使用 html 和 javascript 时遇到了困难。我的 html 页面允许用户选择文本并用颜色突出显示它。现在我想将状态保存到数据库中,以便稍后为该用户显示。当然,我可以在用户编辑后保存整个 html。但我只想保存一些参数,结合原始 html 以用户上次看到的状态显示页面。我们可以使用这个函数:

var index = innerHTML.indexOf(text);

突出显示该索引处的文本。但是如果页面中有很多相同的文本,我想准确地突出显示用户之前突出显示的单词。

任何人都可以指导我如何使用 javascript 完成此操作?

非常感谢您的帮助。

最佳答案

Range 对象和 document.execCommand 允许很容易地操作选择。您遇到的主要问题是以文本格式保存范围对象。

基本上你需要的是获取startContainerstartOffsetendContainerendOffset,它们是创建 Range 对象所需的值。 Offsets 是数字,所以非常简单。容器是节点,你不能直接将其保存为字符串,所以这是主要问题。您可以做的一件事是将 key 添加到您的 DOM 并保存 key 。但是,由于在范围内容器是文本节点,因此您需要保存文本节点的索引。像这样的东西应该允许使用递归函数用键标记 DOM:

function addKey(element) {
if (element.children.length > 0) {
Array.prototype.forEach.call(element.children, function(each, i) {
each.dataset.key = key++;
addKey(each)
});
}
};

addKey(document.body);

完成此操作后,您可以将范围对象转换为可以保存为字符串的对象。像这样:

function rangeToObj(range) {
return {
startKey: range.startContainer.parentNode.dataset.key,
startTextIndex: Array.prototype.indexOf.call(range.startContainer.parentNode.childNodes, range.startContainer),
endKey: range.endContainer.parentNode.dataset.key,
endTextIndex: Array.prototype.indexOf.call(range.endContainer.parentNode.childNodes, range.endContainer),
startOffset: range.startOffset,
endOffset: range.endOffset
}
}

使用它,您可以将用户创建的每个选择保存到一个数组中。像这样:

document.getElementById('textToSelect').addEventListener('mouseup', function(e) {
if (confirm('highlight?')) {
var range = document.getSelection().getRangeAt(0);
selectArray.push(rangeToObj(range));
document.execCommand('hiliteColor', false, 'yellow')
}
});

为了保存亮点,您将每个对象保存为 JSON。要对此进行测试,您可以从范围对象数组中获取 JSON 字符串。像这样(这是使用顶部的获取选择按钮):

document.getElementById('getSelectionString').addEventListener('click', function() {
alert('Copy string to save selections: ' + JSON.stringify(selectArray));
});

然后在加载空 HTML 时,您可以使用反向函数,该函数将从您保存在 JSON 中的对象创建范围。像这样:

function objToRange(rangeStr) {
range = document.createRange();
range.setStart(document.querySelector('[data-key="' + rangeStr.startKey + '"]').childNodes[rangeStr.startTextIndex], rangeStr.startOffset);
range.setEnd(document.querySelector('[data-key="' + rangeStr.endKey + '"]').childNodes[rangeStr.endTextIndex], rangeStr.endOffset);
return range;
}

因此,您可以将字符串中的范围数组转换为对象,然后转换为可以添加的 Range 对象。然后使用 execCommand 设置一些格式。像这样(这是使用顶部的设置选择按钮,刷新 fiddle 后执行此操作):

document.getElementById('setSelection').addEventListener('click', function() {
var selStr = prompt('Paste string');
var selArr = JSON.parse(selStr);
var sel = getSelection();
selArr.forEach(function(each) {
sel.removeAllRanges();
sel.addRange(objToRange(each));
document.execCommand('hiliteColor', false, 'yellow')
})
});

参见:https://jsfiddle.net/sek4tr2f/3/

请注意,在某些情况下这将不起作用,主要的问题情况是用户在已经突出显示的内容中选择内容。这些情况可以处理,但您需要更多条件。

关于javascript - 保存选择文本并稍后在 html 和 javascript 中显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18946573/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com