Diese Lösung funktioniert in allen gängigen Browsern:
saveSelection()
wird an die onmouseup
und onkeyup
-Ereignisse des div angehängt und speichert die Auswahl in der Variablen savedRange
.
restoreSelection()
wird an das onfocus
Ereignis des div angehängt und wählt die in gespeicherte Auswahl erneut aus savedRange
.
Dies funktioniert einwandfrei, es sei denn, Sie möchten, dass die Auswahl wiederhergestellt wird, wenn der Benutzer auch auf das Div klickt (was etwas unintuitiv ist, da Sie normalerweise erwarten, dass der Cursor dorthin geht, wo Sie klicken, der Vollständigkeit halber jedoch Code enthalten).
Um dies zu erreichen, werden die onclick
und onmousedown
Ereignisse von der Funktion abgebrochen, cancelEvent()
die eine browserübergreifende Funktion zum Abbrechen des Ereignisses ist. Die cancelEvent()
Funktion führt die restoreSelection()
Funktion auch aus, da das Div beim Abbrechen des Klickereignisses keinen Fokus erhält und daher überhaupt nichts ausgewählt wird, es sei denn, diese Funktionen werden ausgeführt.
Die Variable isInFocus
speichert, ob sie fokussiert ist und wird in "false" onblur
und "true" geändert onfocus
. Auf diese Weise können Klickereignisse nur abgebrochen werden, wenn das Div nicht im Fokus steht (andernfalls können Sie die Auswahl überhaupt nicht ändern).
Wenn Sie möchten, dass die Auswahl geändert wird, wenn das Div durch einen Klick fokussiert wird, und die Auswahl nicht wiederhergestellt wird onclick
(und nur, wenn das Element programmgesteuert mit document.getElementById("area").focus();
oder ähnlich fokussiert wird, entfernen Sie einfach die Ereignisse onclick
und onmousedown
. Das onblur
Ereignis und die Funktionen onDivBlur()
und cancelEvent()
kann unter diesen Umständen auch sicher entfernt werden.
Dieser Code sollte funktionieren, wenn er direkt in den Text einer HTML-Seite eingefügt wird, wenn Sie ihn schnell testen möchten:
<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
in Nicht-IE-Browsern funktioniert. O_o