Questa soluzione funziona in tutti i principali browser:
saveSelection()
è associato agli eventi onmouseup
e onkeyup
del div e salva la selezione nella variabile savedRange
.
restoreSelection()
è associato onfocus
all'evento del div e seleziona nuovamente la selezione salvata in savedRange
.
Funziona perfettamente a meno che tu non voglia ripristinare la selezione quando l'utente fa clic anche sul div (il che è un po 'poco intuitivo come normalmente ti aspetti che il cursore vada dove fai clic ma il codice è incluso per completezza)
A tale scopo, gli eventi onclick
e onmousedown
vengono annullati dalla funzione cancelEvent()
che è una funzione cross-browser per annullare l'evento. La cancelEvent()
funzione esegue anche la restoreSelection()
funzione perché quando l'evento click viene annullato il div non riceve lo stato attivo e quindi nulla viene selezionato affatto a meno che questa funzione non venga eseguita.
La variabile isInFocus
memorizza se è attiva e viene modificata in "false" onblur
e "true" onfocus
. Ciò consente di annullare gli eventi di clic solo se il div non è attivo (altrimenti non saresti in grado di modificare affatto la selezione).
Se desideri che la selezione venga modificata quando il div è focalizzato da un clic e non ripristina la selezione onclick
(e solo quando il focus è dato all'elemento programmaticamente usando document.getElementById("area").focus();
o simili, rimuovi semplicemente gli eventi onclick
e onmousedown
. L' onblur
evento e le funzioni onDivBlur()
e cancelEvent()
può anche essere rimosso in modo sicuro in queste circostanze.
Questo codice dovrebbe funzionare se rilasciato direttamente nel corpo di una pagina HTML se si desidera testarlo rapidamente:
<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
funzionasse con browser non IE o_o