Giải pháp này hoạt động trong tất cả các trình duyệt chính:
saveSelection()
được gắn vào onmouseup
và onkeyup
các sự kiện của div và lưu lựa chọn vào biến savedRange
.
restoreSelection()
được đính kèm với onfocus
sự kiện của div và chọn lại lựa chọn được lưu trong savedRange
.
Điều này hoạt động hoàn hảo trừ khi bạn muốn khôi phục lựa chọn khi người dùng nhấp vào div aswell (điều này hơi vô tình như bình thường bạn mong muốn con trỏ đi đến nơi bạn nhấp nhưng bao gồm mã để hoàn thành)
Để đạt được điều này onclick
và onmousedown
các sự kiện bị hủy bởi chức năng cancelEvent()
là chức năng trình duyệt chéo để hủy sự kiện. Các cancelEvent()
chức năng cũng chạy restoreSelection()
chức năng bởi vì khi sự kiện click bị hủy div không nhận được tập trung và do đó không có gì được chọn ở tất cả trừ khi chức năng này được chạy.
Biến isInFocus
lưu trữ cho dù nó nằm trong tiêu điểm và được thay đổi thành "false" onblur
và "true" onfocus
. Điều này cho phép các sự kiện nhấp chỉ bị hủy nếu div không tập trung (nếu không bạn hoàn toàn không thể thay đổi lựa chọn).
Nếu bạn muốn lựa chọn được thay đổi khi div được tập trung bởi một nhấp chuột, và không khôi phục lại lựa chọn onclick
(và chỉ khi tập trung được trao cho các phần tử programtically sử dụng document.getElementById("area").focus();
hoặc tương tự sau đó chỉ cần loại bỏ các onclick
và onmousedown
các sự kiện. Các onblur
sự kiện và onDivBlur()
vàcancelEvent()
chức năng cũng có thể được gỡ bỏ một cách an toàn trong những trường hợp này.
Mã này sẽ hoạt động nếu được thả trực tiếp vào phần thân của trang html nếu bạn muốn kiểm tra nhanh:
<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)//non IE Browsers
{
savedRange = window.getSelection().getRangeAt(0);
}
else if(document.selection)//IE
{
savedRange = document.selection.createRange();
}
}
function restoreSelection()
{
isInFocus = true;
document.getElementById("area").focus();
if (savedRange != null) {
if (window.getSelection)//non IE and there is already a selection
{
var s = window.getSelection();
if (s.rangeCount > 0)
s.removeAllRanges();
s.addRange(savedRange);
}
else if (document.createRange)//non IE and no selection
{
window.getSelection().addRange(savedRange);
}
else if (document.selection)//IE
{
savedRange.select();
}
}
}
//this part onwards is only needed if you want to restore selection onclick
var isInFocus = false;
function onDivBlur()
{
isInFocus = false;
}
function cancelEvent(e)
{
if (isInFocus == false && savedRange != null) {
if (e && e.preventDefault) {
//alert("FF");
e.stopPropagation(); // DOM style (return false doesn't always work in FF)
e.preventDefault();
}
else {
window.event.cancelBubble = true;//IE stopPropagation
}
restoreSelection();
return false; // false = IE style
}
}
</script>
contentEditable
đã làm việc trong các trình duyệt không phải IE o_o