3 回答
TA贡献1853条经验 获得超6个赞
var editable = document.getElementById('editable'), selection, range;// Populates selection and range variablesvar captureSelection = function(e) { // Don't capture selection outside editable region var isOrContainsAnchor = false, isOrContainsFocus = false, sel = window.getSelection(), parentAnchor = sel.anchorNode, parentFocus = sel.focusNode; while(parentAnchor && parentAnchor != document.documentElement) { if(parentAnchor == editable) { isOrContainsAnchor = true; } parentAnchor = parentAnchor.parentNode; } while(parentFocus && parentFocus != document.documentElement) { if(parentFocus == editable) { isOrContainsFocus = true; } parentFocus = parentFocus.parentNode; } if(!isOrContainsAnchor || !isOrContainsFocus) { return; } selection = window.getSelection(); // Get range (standards) if(selection.getRangeAt !== undefined) { range = selection.getRangeAt(0); // Get range (Safari 2) } else if( document.createRange && selection.anchorNode && selection.anchorOffset && selection.focusNode && selection.focusOffset ) { range = document.createRange(); range.setStart(selection.anchorNode, selection.anchorOffset); range.setEnd(selection.focusNode, selection.focusOffset); } else { // Failure here, not handled by the rest of the script. // Probably IE or some older browser }};// Recalculate selection while typingeditable.onkeyup = captureSelection; // Recalculate selection after clicking/drag-selectingeditable.onmousedown = function(e) { editable.className = editable.className + ' selecting';};document.onmouseup = function(e) { if(editable.className.match(/\sselecting(\s|$)/)) { editable.className = editable.className.replace(/ selecting(\s|$)/, ''); captureSelection(); }};editable.onblur = function(e) { var cursorStart = document.createElement('span'), collapsed = !!range.collapsed; cursorStart.id = 'cursorStart'; cursorStart.appendChild(document.createTextNode('—')); // Insert beginning cursor marker range.insertNode(cursorStart); // Insert end cursor marker if any text is selected if(!collapsed) { var cursorEnd = document.createElement('span'); cursorEnd.id = 'cursorEnd'; range.collapse(); range.insertNode(cursorEnd); }};// Add callbacks to afterFocus to be called after cursor is replaced // if you like, this would be useful for styling buttons and so onvar afterFocus = [];editable.onfocus = function(e) { // Slight delay will avoid the initial selection // (at start or of contents depending on browser) being mistaken setTimeout(function() { var cursorStart = document.getElementById('cursorStart'), cursorEnd = document.getElementById('cursorEnd'); // Don't do anything if user is creating a new selection if(editable.className.match(/\sselecting(\s|$)/)) { if(cursorStart) { cursorStart.parentNode.removeChild(cursorStart); } if(cursorEnd) { cursorEnd.parentNode.removeChild(cursorEnd); } } else if(cursorStart) { captureSelection(); var range = document.createRange(); if(cursorEnd) { range.setStartAfter(cursorStart); range.setEndBefore(cursorEnd); // Delete cursor markers cursorStart.parentNode.removeChild(cursorStart); cursorEnd.parentNode.removeChild(cursorEnd); // Select range selection.removeAllRanges(); selection.addRange(range); } else { range.selectNode(cursorStart); // Select range selection.removeAllRanges(); selection.addRange(range); // Delete cursor marker document.execCommand('delete', false, null); } } // Call callbacks here for(var i = 0; i < afterFocus.length; i++) { afterFocus[i](); } afterFocus = []; // Register selection again captureSelection(); }, 10);};
TA贡献1805条经验 获得超10个赞
此解决方案适用于所有主要浏览器:
saveSelection()
onmouseup
onkeyup
savedRange
.
restoreSelection()
onfocus
savedRange
.
onclick
onmousedown
cancelEvent()
cancelEvent()
restoreSelection()
isInFocus
onblur
onfocus
onclick
document.getElementById("area").focus();
onclick
onmousedown
onblur
onDivBlur()
cancelEvent()
<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 onclickvar 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>
TA贡献1775条经验 获得超11个赞
添加回答
举报