このソリューションは、すべての主要なブラウザーで機能します。
saveSelection()
はdivのonmouseup
およびonkeyup
イベントにアタッチされ、選択を変数に保存しますsavedRange
。
restoreSelection()
はonfocus
div のイベントにアタッチされ、に保存された選択を再選択しsavedRange
ます。
これは、ユーザーがdivをクリックしたときに選択を復元したい場合を除いて、完全に機能します(通常、カーソルはクリックした場所に移動すると予想されますが、完全を期すためにコードが含まれているため、少し直観的ではありません)。
これを達成するためにonclick
、onmousedown
イベントはイベントをキャンセルcancelEvent()
するクロスブラウザ機能である関数によってキャンセルされます。このcancelEvent()
関数は関数も実行しrestoreSelection()
ます。これは、クリックイベントがキャンセルされると、divがフォーカスを受け取らず、この関数が実行されない限り、何も選択されないためです。
変数isInFocus
は、フォーカスがあるかどうかを格納し、 "false" onblur
および "true"に変更されますonfocus
。これにより、divがフォーカスされていない場合にのみクリックイベントをキャンセルできます(それ以外の場合は、選択をまったく変更できません)。
divがクリックによってフォーカスされたときに選択を変更し、選択を復元しonclick
ない場合(およびプログラムを使用して要素にフォーカスが与えられている場合のみ)とイベントをdocument.getElementById("area").focus();
削除します。イベントとと関数これらの状況でも安全に削除できます。onclick
onmousedown
onblur
onDivBlur()
cancelEvent()
このコードをHTMLページの本文に直接ドロップすると、すばやくテストしたい場合に機能します。
<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
IE以外のブラウザで動作することを知りませんでしたo_o