kok*_*oko 5 javascript jquery range selection contenteditable
我正在尝试存储一个contentEditable元素的选择,并在以后恢复它.
我想观察paste事件并存储以前的HTML,清除html然后手动插入粘贴的文本,在所选位置进行一些更改.
看一下这个例子:jsfiddle.net/gEhjZ
当您选择文本的一部分时,点击store,再次删除选择并点击restore,它按预期工作.
但是当你第一次点击时store,然后通过点击替换完全相同的HTML overwrite html,然后尝试restore,没有任何反应.
我认为使用.cloneRange()会有所作为,但事实并非如此.即使是object($.extend(true, {}, oldRange))的深层副本也无法解决问题.只要我覆盖HTML,选择对象sel也会被更改.对我来说,更改选择上下文会擦除范围是有道理的,但我正在尝试将其恢复为完全相同的HTML.
我知道我可以使用rangy,但我真的不想为这个小功能使用一个巨大的库.我错过了什么?任何帮助将非常感激!
注意:只有Firefox/Chrome,因此不需要使用crossbrowser-hacks.
@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)当然,
我认为我必须使用它.但现在start和endiframe的选择是0看snipt.org/AJah2
Tim*_*own 14
您可以使用以下函数保存和恢复角色位置:
我已经稍微调整了这些功能,以便为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();
};
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4500 次 |
| 最近记录: |