本文介绍了在 contentEditable <div> 上设置光标位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当 contentEditable='on'

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

我相信当他们离开 div 焦点时,我必须将当前光标位置存储在一个变量中,然后当他们再次获得焦点时重新设置它,但我无法放在一起,或者找到一个有效的代码示例.

如果有人有任何想法、工作代码片段或示例,我很乐意看到它们.

我还没有任何代码,但这是我所拥有的:

<div id="area" contentEditable="true"></div>

附注.我已经尝试过这个资源,但它似乎不适用于

.也许仅适用于 textarea (如何将光标移动到 contenteditable 实体的末尾)

解决方案

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

var editable = document.getElementById('editable'),选择、范围;//填充选择和范围变量var captureSelection = function(e) {//不要在可编辑区域之外捕获选择var isOrContainsAnchor = false,isOrContainsFocus = false,sel = window.getSelection(),parentAnchor = sel.anchorNode,parentFocus = sel.focusNode;while(parentAnchor && parentAnchor != document.documentElement) {如果(父锚 == 可编辑){isOrContainsAnchor = true;}parentAnchor = parentAnchor.parentNode;}while(parentFocus && parentFocus != document.documentElement) {如果(父焦点 == 可编辑){isOrContainsFocus = true;}parentFocus = parentFocus.parentNode;}if(!isOrContainsAnchor || !isOrContainsFocus) {返回;}selection = window.getSelection();//获取范围(标准)if(selection.getRangeAt !== undefined) {范围 = selection.getRangeAt(0);//获取范围(Safari 2)}否则如果(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);} 别的 {//此处失败,脚本的其余部分未处理.//可能是 IE 或一些较旧的浏览器}};//输入时重新计算选择editable.onkeyup = captureSelection;//点击/拖动选择后重新计算选择editable.onmousedown = 函数(e){editable.className = editable.className + '选择';};document.onmouseup = 函数(e){if(editable.className.match(/sselecting(s|$)/)) {editable.className = editable.className.replace(/selection(s|$)/, '');捕获选择();}};editable.onblur = 函数(e){var cursorStart = document.createElement('span'),折叠 = !!range.collapsed;cursorStart.id = 'cursorStart';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){//稍微延迟会避免初始选择//(在开始或内容取决于浏览器)被错误设置超时(功能(){var cursorStart = document.getElementById('cursorStart'),cursorEnd = document.getElementById('cursorEnd');//如果用户正在创建一个新的选择,不要做任何事情if(editable.className.match(/sselecting(s|$)/)) {如果(光标开始){cursorStart.parentNode.removeChild(cursorStart);}如果(光标结束){cursorEnd.parentNode.removeChild(cursorEnd);}} else if(cursorStart) {捕获选择();var range = document.createRange();如果(光标结束){range.setStartAfter(cursorStart);range.setEndBefore(cursorEnd);//删除光标标记cursorStart.parentNode.removeChild(cursorStart);cursorEnd.parentNode.removeChild(cursorEnd);//选择范围selection.removeAllRanges();selection.addRange(range);} 别的 {range.selectNode(cursorStart);//选择范围selection.removeAllRanges();selection.addRange(range);//删除光标标记document.execCommand('delete', false, null);}}//在这里调用回调for(var i = 0; i < afterFocus.length; i++) {afterFocus[i]();}afterFocus = [];//再次注册选择捕获选择();}, 10);};

I am after a definitive, cross-browser solution to set the cursor/caret position to the last known position when a contentEditable='on' <div> regains focus. It appears default functionality of a content editable div is to move the caret/cursor to the beginning of the text in the div each time you click on it, which is undesirable.

I believe I would have to store in a variable the current cursor position when they are leaving focus of the div, and then re-set this when they have focus inside again, but I have not been able to put together, or find a working code sample yet.

If anybody has any thoughts, working code snippets or samples I'd be happy to see them.

I don't really have any code yet but here is what I do have:

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

PS. I have tried this resource but it appears it does not work for a <div>. Perhaps only for textarea (How to move cursor to end of contenteditable entity)

解决方案

This is compatible with the standards-based browsers, but will probably fail in IE. I'm providing it as a starting point. IE doesn't support DOM Range.

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);
};

这篇关于在 contentEditable <div> 上设置光标位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 20:36