此解决方案适用于所有主要浏览器:
saveSelection()
附加到div的onmouseup
和onkeyup
事件并将选择保存到变量savedRange
。
restoreSelection()
附加到onfocus
div的事件并重新选择保存在savedRange
.
这非常有效,除非您希望在用户单击 div 时恢复选择(这有点不直观,因为通常您希望光标移动到您单击的位置,但为了完整性而包含代码)
为了实现这一点onclick
,onmousedown
事件被取消的函数cancelEvent()
是一个跨浏览器的函数来取消事件。该cancelEvent()
函数还运行该restoreSelection()
函数,因为当单击事件被取消时,div 不会获得焦点,因此除非运行此函数,否则根本不会选择任何内容。
变量isInFocus
存储是否处于焦点,并更改为 "false"onblur
和 "true" onfocus
。这允许仅在 div 未处于焦点时取消单击事件(否则您根本无法更改选择)。
如果您希望在通过单击聚焦 div 时更改选择,而不是恢复选择onclick
(并且仅当使用document.getElementById("area").focus();
或类似方法以编程方式将焦点赋予元素时,则只需删除onclick
andonmousedown
事件。onblur
事件和onDivBlur()
andcancelEvent()
函数在这些情况下也可以安全地移除。
如果您想快速测试此代码,如果将其直接放入 html 页面的正文中,则它应该可以工作:
<div id="area" style="width:300px;height:300px;" onblur="onDivBlur();" onmousedown="return cancelEvent(event);" onclick="return cancelEvent(event);" contentEditable="true" onmouseup="saveSelection();" onkeyup="saveSelection();" onfocus="restoreSelection();"></div>
<script type="text/javascript">
var savedRange,isInFocus;
function saveSelection()
{
if(window.getSelection)
{
savedRange = window.getSelection().getRangeAt(0);
}
else if(document.selection)
{
savedRange = document.selection.createRange();
}
}
function restoreSelection()
{
isInFocus = true;
document.getElementById("area").focus();
if (savedRange != null) {
if (window.getSelection)
{
var s = window.getSelection();
if (s.rangeCount > 0)
s.removeAllRanges();
s.addRange(savedRange);
}
else if (document.createRange)
{
window.getSelection().addRange(savedRange);
}
else if (document.selection)
{
savedRange.select();
}
}
}
var isInFocus = false;
function onDivBlur()
{
isInFocus = false;
}
function cancelEvent(e)
{
if (isInFocus == false && savedRange != null) {
if (e && e.preventDefault) {
e.stopPropagation();
e.preventDefault();
}
else {
window.event.cancelBubble = true;
}
restoreSelection();
return false;
}
}
</script>