Javascript 在contentEditable上设置光标位置<;部门>;

Javascript 在contentEditable上设置光标位置<;部门>;,javascript,jquery,html,contenteditable,cursor-position,Javascript,Jquery,Html,Contenteditable,Cursor Position,我想要的是一个明确的跨浏览器解决方案,当contentEditable='on'重新获得焦点时,将光标/插入符号位置设置为最后一个已知的位置。内容可编辑div的默认功能似乎是每次单击时将插入符号/光标移动到div中文本的开头,这是不可取的 var range = document.createRange(); range.setStart(o_div.childNodes[0],last_caret_pos); range.setEnd(o_div.childNodes[0],last_car

我想要的是一个明确的跨浏览器解决方案,当contentEditable='on'重新获得焦点时,将光标/插入符号位置设置为最后一个已知的位置。内容可编辑div的默认功能似乎是每次单击时将插入符号/光标移动到div中文本的开头,这是不可取的

var range = document.createRange();

range.setStart(o_div.childNodes[0],last_caret_pos);
range.setEnd(o_div.childNodes[0],last_caret_pos);
range.collapse(false);

var sel = window.getSelection(); 
sel.removeAllRanges();
sel.addRange(range);
我相信,当它们离开div的焦点时,我必须将当前光标位置存储在一个变量中,然后在它们再次进入焦点时重新设置该位置,但我还无法将它们放在一起,或者找到一个工作代码示例

var range = document.createRange();

range.setStart(o_div.childNodes[0],last_caret_pos);
range.setEnd(o_div.childNodes[0],last_caret_pos);
range.collapse(false);

var sel = window.getSelection(); 
sel.removeAllRanges();
sel.addRange(range);
如果有人有任何想法、工作代码片段或示例,我很乐意看到他们

var range = document.createRange();

range.setStart(o_div.childNodes[0],last_caret_pos);
range.setEnd(o_div.childNodes[0],last_caret_pos);
range.collapse(false);

var sel = window.getSelection(); 
sel.removeAllRanges();
sel.addRange(range);
我还没有真正的代码,但我有:

<script type="text/javascript">
// jQuery
$(document).ready(function() {
   $('#area').focus(function() { .. }  // focus I would imagine I need.
}
</script>
<div id="area" contentEditable="true"></div>
var range = document.createRange();

range.setStart(o_div.childNodes[0],last_caret_pos);
range.setEnd(o_div.childNodes[0],last_caret_pos);
range.collapse(false);

var sel = window.getSelection(); 
sel.removeAllRanges();
sel.addRange(range);

//jQuery
$(文档).ready(函数(){
$('#area').focus(function(){..}//focus我想我需要它。
}

另外,我尝试了此资源,但它似乎不适用于。可能仅适用于textarea()

这与基于标准的浏览器兼容,但在IE中可能会失败。我将其作为起点提供。IE不支持DOM范围

var editable = document.getElementById('editable'),
    selection, range;

// Populates selection and range variables
var 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 typing
editable.onkeyup = captureSelection;

// Recalculate selection after clicking/drag-selecting
editable.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 on
var 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);
};
var range = document.createRange();

range.setStart(o_div.childNodes[0],last_caret_pos);
range.setEnd(o_div.childNodes[0],last_caret_pos);
range.collapse(false);

var sel = window.getSelection(); 
sel.removeAllRanges();
sel.addRange(range);
var editable=document.getElementById('editable'),
选择、范围;
//填充选择和范围变量
var captureSelection=功能(e){
//不捕获可编辑区域外的选择
var isOrContainsAnchor=false,
isOrContainsFocus=false,
sel=window.getSelection(),
parentAnchor=sel.anchorNode,
parentFocus=sel.focusNode;
while(parentAnchor&&parentAnchor!=document.documentElement){
如果(parentAnchor==可编辑){
isOrContainsAnchor=true;
}
parentAnchor=parentAnchor.parentNode;
}
while(parentFocus&&parentFocus!=document.documentElement){
if(parentFocus==可编辑){
isOrContainsFocus=真;
}
parentFocus=parentFocus.parentNode;
}
如果(!isOrContainsAnchor | |!isOrContainsFocus){
返回;
}
selection=window.getSelection();
//获取范围(标准)
if(selection.getRangeAt!==未定义){
范围=选择。getRangeAt(0);
//获取范围(Safari 2)
}否则如果(
document.createRange&&
锚链选择&&
主播偏移量&&
选择焦点节点&&
选择焦点偏移量
) {
range=document.createRange();
range.setStart(selection.anchorNode,selection.anchorOffset);
range.setEnd(selection.focusNode,selection.focusOffset);
}否则{
//此处失败,而不是由脚本的其余部分处理。
//可能是IE或一些旧的浏览器
}
};
//键入时重新计算所选内容
editable.onkeyup=captureSelection;
//单击/拖动选择后重新计算选择
editable.onmousedown=函数(e){
editable.className=editable.className+“正在选择”;
};
document.onmouseup=函数(e){
if(可编辑的.className.match(/\s选择(\s |$)/){
editable.className=editable.className.replace(/正在选择(\s |$)/,“”);
captureSelection();
}
};
editable.onblur=函数(e){
var cursorStart=document.createElement('span'),
折叠=!!range.collapsed;
cursorStart.id='cursorStart';
appendChild(document.createTextNode('-');
//插入起始光标标记
range.insertNode(cursorStart);
//如果选择了任何文本,请插入结束光标标记
如果(!崩溃){
var cursorEnd=document.createElement('span');
cursorEnd.id='cursorEnd';
range.collapse();
range.insertNode(cursorEnd);
}
};
//将回调添加到替换光标后要调用的afterFocus
//如果您愿意,这将有助于设置按钮样式等
var afterFocus=[];
editable.onfocus=函数(e){
//稍微延迟将避免初始选择
//(在内容的开头或结尾,取决于浏览器)出错
setTimeout(函数(){
var cursorStart=document.getElementById('cursorStart'),
cursorEnd=document.getElementById('cursorEnd');
//如果用户正在创建新选择,请不要执行任何操作
if(可编辑的.className.match(/\s选择(\s |$)/){
如果(光标开始){
cursorStart.parentNode.removeChild(cursorStart);
}
如果(光标结束){
cursorEnd.parentNode.removeChild(cursorEnd);
}
}else if(光标开始){
captureSelection();
var range=document.createRange();
如果(光标结束){
范围.setStartAfter(游标开始);
range.setEndBefore(cursorEnd);
//删除光标标记
cursorStart.parentNode.removeChild(cursorStart);
cursorEnd.parentNode.removeChild(cursorEnd);
//选择范围
selection.removeAllRanges();
选择。添加范围(范围);
}否则{
范围。选择节点(光标开始);
//选择范围
selection.removeAllRanges();
选择。添加范围(范围);
//删除光标标记
document.execCommand('delete',false,null);
}
}
//在这里回电话
对于(变量i=0;i
更新

var range = document.createRange();

range.setStart(o_div.childNodes[0],last_caret_pos);
range.setEnd(o_div.childNodes[0],last_caret_pos);
range.collapse(false);

var sel = window.getSelection(); 
sel.removeAllRanges();
sel.addRange(range);
我已经编写了一个名为的跨浏览器范围和选择库,其中包含了我在下面发布的代码的改进版本。对于这个特定的问题,您可以使用,尽管我可能会尝试使用类似于如果您不在项目中对选择做任何其他事情,并且不需要大量的库

var range = document.createRange();

range.setStart(o_div.childNodes[0],last_caret_pos);
range.setEnd(o_div.childNodes[0],last_caret_pos);
range.collapse(false);

var sel = window.getSelection(); 
sel.removeAllRanges();
sel.addRange(range);
上一个
var el = document.getElementById('idOfYoursContentEditable');
var selection = window.getSelection();
var range = document.createRange();
selection.removeAllRanges();
range.selectNodeContents(el);
range.collapse(false);
selection.addRange(range);
el.focus();