Solusi ini berfungsi di semua browser utama:
saveSelection()
dilampirkan ke onmouseup
dan onkeyup
acara div dan menyimpan pilihan ke variabel savedRange
.
restoreSelection()
terlampir pada onfocus
acara div dan memilih kembali seleksi disimpan savedRange
.
Ini berfungsi dengan baik kecuali jika Anda ingin pilihan dikembalikan ketika pengguna mengklik div juga (yang agak tidak intuitif seperti biasanya Anda mengharapkan kursor pergi ke mana Anda mengklik tetapi kode termasuk untuk kelengkapan)
Untuk mencapai ini onclick
dan onmousedown
acara dibatalkan oleh fungsi cancelEvent()
yang merupakan fungsi lintas browser untuk membatalkan acara. The cancelEvent()
Fungsi juga menjalankan restoreSelection()
fungsi karena sebagai acara klik dibatalkan div tidak menerima fokus dan oleh karena itu tidak ada yang dipilih sama sekali kecuali fungsi ini dijalankan.
Variabel isInFocus
menyimpan apakah itu dalam fokus dan diubah menjadi "false" onblur
dan "true" onfocus
. Ini memungkinkan acara klik dibatalkan hanya jika div tidak dalam fokus (jika tidak, Anda tidak akan dapat mengubah pilihan sama sekali).
Jika Anda ingin pemilihan diubah ketika div difokuskan dengan klik, dan tidak mengembalikan pilihan onclick
(dan hanya ketika fokus diberikan kepada elemen yang menggunakan document.getElementById("area").focus();
atau serupa secara terprogram maka cukup hapus onclick
dan onmousedown
acara. onblur
Acara dan onDivBlur()
dan cancelEvent()
fungsi juga dapat dengan aman dihilangkan dalam kondisi ini.
Kode ini akan berfungsi jika dijatuhkan langsung ke badan laman html jika Anda ingin mengujinya dengan cepat:
<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
bekerja di browser non-IE o_o