Javascript 无法在HTML修改后恢复选择,即使它是相同的HTML
我正在尝试存储contentEditable元素的选择,并在以后还原它 我想观察粘贴事件并像以前一样存储HTML,清除HTML,然后在所选位置手动插入粘贴的文本并进行一些更改 看看这个例子: 当您选择文本的一部分时,点击store,再次删除所选内容并点击restore,它将按预期工作 但是,当您第一次点击store,然后点击overwrite HTML,用完全相同的HTML替换HTML,然后尝试恢复时,什么也没有发生 我认为使用.cloneRange会有所不同,但不会。即使是对象$.extendtrue,{},oldRange的深度副本也不会起作用。一旦我覆盖HTML,选择对象sel也会被更改。对我来说,更改选择上下文将删除范围是有意义的,但我正在尝试将其还原为完全相同的HTML 我知道我可以使用,但我真的不想为了这个小功能而使用一个巨大的库。我错过了什么?任何帮助都将不胜感激 注意:只有Firefox/Chrome,所以不需要交叉浏览器 更新: @Tim Down的答案在使用div时有效,但实际上我使用的是iframe。当我举这个例子时,我认为这不会有任何区别 现在,当我尝试恢复iframe的主体时,我得到以下错误:TypeError:Value未实现接口节点。在下一行的预选范围中。选择NodeContentsContainerEL;。我没有从谷歌搜索中得到多少。我试图包装正文的内容并恢复包装的html,但我得到了相同的错误 在这种情况下,jsfiddle不起作用,因为它使用iframe来显示结果本身,所以我在这里举了一个例子: 同样,不带包装: 更新2:Javascript 无法在HTML修改后恢复选择,即使它是相同的HTML,javascript,jquery,range,selection,contenteditable,Javascript,Jquery,Range,Selection,Contenteditable,我正在尝试存储contentEditable元素的选择,并在以后还原它 我想观察粘贴事件并像以前一样存储HTML,清除HTML,然后在所选位置手动插入粘贴的文本并进行一些更改 看看这个例子: 当您选择文本的一部分时,点击store,再次删除所选内容并点击restore,它将按预期工作 但是,当您第一次点击store,然后点击overwrite HTML,用完全相同的HTML替换HTML,然后尝试恢复时,什么也没有发生 我认为使用.cloneRange会有所不同,但不会。即使是对象$.extend
当然,我想我必须使用editable.get0。但是现在iframe选择的开始和结束是0。请参见您可以使用以下功能保存和恢复角色位置: 我稍微调整了这些函数,以用于iframe中的元素 演示: 代码:
非常感谢,该范围现在已正确保存,但不知怎的,它无法恢复选择@koko:初始脚本运行时,iframe文档可能没有完全加载。我建议在单击处理程序中使用$'iframe'.contents.find'body'[0]而不是editable.get0。文档已完全加载,我将在粘贴事件中调用此函数。但是,doc变量是未定义的containerrel.ownerDocument。Chrome并不介意,而Firefox介意。稍后我会看一看,我想剩下的问题会相对容易解决。@koko:containerEl.ownerDocument未定义表示containerEl有问题,例如已从文档中删除。不过我想有一个限制。将光标放置在下一空行的开头并保存所选内容,恢复所选内容时,将光标放置在上一行的末尾。有没有办法克服它??
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();
};
}