To rozwiązanie działa we wszystkich głównych przeglądarkach:
saveSelection()jest dołączony do zdarzeń onmouseupi onkeyupelementu div i zapisuje wybór w zmiennej savedRange.
restoreSelection()jest dołączony do onfocuszdarzenia div i ponownie wybiera zaznaczenie zapisane w savedRange.
Działa to doskonale, chyba że chcesz, aby zaznaczenie zostało przywrócone, gdy użytkownik kliknie również element div (co jest trochę nieintuicyjne, ponieważ zwykle oczekujesz, że kursor znajdzie się w miejscu kliknięcia, ale kod zawiera kompletność)
Aby to osiągnąć, zdarzenia onclicki onmousedownsą anulowane przez funkcję, cancelEvent()która jest funkcją cross browser do anulowania zdarzenia. cancelEvent()Funkcja działa również restoreSelection()funkcję ponieważ jako zdarzenie click jest anulowane div nie odbiera ostrość i dlatego nic nie jest zaznaczone w ogóle, chyba że jest to uruchomić funkcje.
Zmienna isInFocusprzechowuje, czy jest fokus, i jest zmieniana na „false” onbluri „true”onfocus . Dzięki temu zdarzenia kliknięcia mogą być anulowane tylko wtedy, gdy element div nie jest aktywny (w przeciwnym razie nie można by w ogóle zmienić zaznaczenia).
Jeśli chcesz, aby zaznaczenie onclickuległo zmianie, gdy element div jest skupiony przez kliknięcie, i nie chcesz go przywracać (i tylko wtedy, gdy fokus zostanie nadany elementowi programowo za pomocą document.getElementById("area").focus();lub podobnie, po prostu usuń zdarzenia onclicki onmousedown. onblurZdarzenie onDivBlur()i cancelEvent()funkcje i w takich okolicznościach można również bezpiecznie usunąć.
Ten kod powinien działać, jeśli zostanie umieszczony bezpośrednio w treści strony html, jeśli chcesz go szybko przetestować:
<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>
contentEditablepracował w przeglądarkach innych niż IE-O_o