Cette solution fonctionne dans tous les principaux navigateurs :
saveSelection()
est attaché à la onmouseup
y onkeyup
de la div et enregistre la sélection dans la variable savedRange
.
restoreSelection()
est attaché à la onfocus
de la div et resélectionne la sélection sauvegardée dans le fichier savedRange
.
Cela fonctionne parfaitement, à moins que vous ne souhaitiez que la sélection soit restaurée lorsque l'utilisateur clique sur le div (ce qui n'est pas très intuitif car normalement le curseur doit aller là où vous cliquez, mais le code est inclus pour être complet).
Pour y parvenir, la onclick
y onmousedown
sont annulés par la fonction cancelEvent()
qui est une fonction de navigateur croisé pour annuler l'événement. Le site cancelEvent()
exécute également la fonction restoreSelection()
car comme l'événement de clic est annulé, la division ne reçoit pas le focus et donc rien n'est sélectionné du tout à moins que cette fonction ne soit exécutée.
La variable isInFocus
enregistre s'il est au point et est changé en "faux". onblur
et "vrai" onfocus
. Cela permet d'annuler les événements de clics uniquement si la div n'est pas en focus (sinon vous ne pourriez pas du tout modifier la sélection).
Si vous souhaitez que la sélection soit modifiée lorsqu'un clic est effectué sur la division, et que la sélection ne soit pas rétablie. onclick
(et seulement lorsque le focus est donné à l'élément de façon programmatique en utilisant le bouton document.getElementById("area").focus();
ou similaire, il suffit de supprimer le onclick
y onmousedown
événements. Le site onblur
et l'événement onDivBlur()
y cancelEvent()
Les fonctions peuvent également être supprimées en toute sécurité dans ces circonstances.
Ce code devrait fonctionner si vous le déposez directement dans le corps d'une page html si vous voulez le tester rapidement :
<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>
0 votes
Je ne savais pas.
contentEditable
fonctionne dans les navigateurs non-IE o_o10 votes
Oui, c'est vrai, Aditya.
5 votes
Aditya, Safari 2+, Firefox 3+ je crois.
0 votes
Essayez de définir tabindex="0" sur le div. Cela devrait permettre de le mettre en évidence dans la plupart des navigateurs.