gpt4 book ai didi

javascript - HTML 修改后无法恢复选择,即使是相同的 HTML

转载 作者:数据小太阳 更新时间:2023-10-29 05:46:48 24 4
gpt4 key购买 nike

我正在尝试存储对 contentEditable 元素的选择并在以后恢复它。

我想观察 paste 事件并像以前一样存储 HTML,清除 html,然后在选定位置手动插入粘贴的文本并进行一些更改。

看看这个例子:jsfiddle.net/gEhjZ

当您选择文本的一部分时,点击 store,再次删除选择并点击 restore,它按预期工作。

但是当您第一次点击 store 时,然后通过点击 overwrite html 将 HTML 替换为完全相同的 HTML,然后尝试 restore,没有任何反应。

我认为使用 .cloneRange() 会有所作为,但事实并非如此。即使对象的深拷贝 ($.extend(true, {}, oldRange)) 也无法解决问题。一旦我覆盖了 HTML,选择对象 sel 也被改变了。对我来说,更改选择上下文会删除范围,但我正在尝试为完全相同的 HTML 恢复它。

我知道我可以使用 rangy ,但我真的不想为了这个小功能而使用庞大的库。我错过了什么?任何帮助将不胜感激!

注意:仅限 Firefox/Chrome,因此无需跨浏览器破解。

更新:

@Tim Down 的回答在使用 div 时有效,但我实际上使用的是 iframe。当我举那个例子时,我认为它不会有任何不同。

现在,当我尝试恢复 iframe 的主体时,出现以下错误:TypeError: Value does not implement interface Node. 在以下行 preSelectionRange.selectNodeContents(containerEl);。我没有从谷歌搜索中得到太多。我试图包装正文的内容并恢复包装的 html,但我得到了同样的错误。

jsfiddle 在这种情况下不起作用,因为它使用 iframe 来显示结果本身,所以我在这里举了一个例子:snipt.org/AJad3

同样没有换行:snipt.org/AJaf0

更新 2:我认为我当然必须使用 editable.get(0)。但是现在 iframe 选择的 startend 是 0。参见 snipt.org/AJah2

最佳答案

您可以使用如下函数保存和恢复字符位置:

https://stackoverflow.com/a/13950376/96100

我稍微调整了这些函数以适用于 iframe 中的元素。

演示:http://jsfiddle.net/timdown/gEhjZ/4/

代码:

var saveSelection, restoreSelection;

if (window.getSelection && document.createRange) {
saveSelection = function(containerEl) {
var doc = containerEl.ownerDocument, win = doc.defaultView;
var range = win.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(containerEl);
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;

return {
start: start,
end: start + range.toString().length
};
};

restoreSelection = function(containerEl, savedSel) {
var doc = containerEl.ownerDocument, win = doc.defaultView;
var charIndex = 0, range = doc.createRange();
range.setStart(containerEl, 0);
range.collapse(true);
var nodeStack = [containerEl], node, foundStart = false, stop = false;

while (!stop && (node = nodeStack.pop())) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
range.setStart(node, savedSel.start - charIndex);
foundStart = true;
}
if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
range.setEnd(node, savedSel.end - charIndex);
stop = true;
}
charIndex = nextCharIndex;
} else {
var i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i]);
}
}
}

var sel = win.getSelection();
sel.removeAllRanges();
sel.addRange(range);
};
} else if (document.selection) {
saveSelection = function(containerEl) {
var doc = containerEl.ownerDocument, win = doc.defaultView || doc.parentWindow;
var selectedTextRange = doc.selection.createRange();
var preSelectionTextRange = doc.body.createTextRange();
preSelectionTextRange.moveToElementText(containerEl);
preSelectionTextRange.setEndPoint("EndToStart", selectedTextRange);
var start = preSelectionTextRange.text.length;

return {
start: start,
end: start + selectedTextRange.text.length
};
};

restoreSelection = function(containerEl, savedSel) {
var doc = containerEl.ownerDocument, win = doc.defaultView || doc.parentWindow;
var textRange = doc.body.createTextRange();
textRange.moveToElementText(containerEl);
textRange.collapse(true);
textRange.moveEnd("character", savedSel.end);
textRange.moveStart("character", savedSel.start);
textRange.select();
};
}

关于javascript - HTML 修改后无法恢复选择,即使是相同的 HTML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17678843/

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