繁体   English   中英

如何使用 html 子元素在 contenteditable div 中获取插入符号 position?

[英]How to get caret position within contenteditable div with html child elements?

我正在使用一个 contenteditable div,它可以选择在文本流中包含内联 html 元素,例如标签。

在某些时候,我需要获取插入符 position,但发现如果插入符位于 html 子元素之后,则使用示例代码返回的 position 是不正确的。

我需要一个跨浏览器解决方案,它允许我存储插入符号的 position,以便即使在文本流中存在 html 元素的情况下也可以稍后恢复它。

例子:

 function getCaretPosition(editableDiv) { var caretPos = 0, containerEl = null, sel, range; if (window.getSelection) { sel = window.getSelection(); if (sel.rangeCount) { range = sel.getRangeAt(0); if (range.commonAncestorContainer.parentNode == editableDiv) { caretPos = range.endOffset; } } } else if (document.selection && document.selection.createRange) { range = document.selection.createRange(); if (range.parentElement() == editableDiv) { var tempEl = document.createElement("span"); editableDiv.insertBefore(tempEl, editableDiv.firstChild); var tempRange = range.duplicate(); tempRange.moveToElementText(tempEl); tempRange.setEndPoint("EndToEnd", range); caretPos = tempRange.text.length; } } return caretPos; } $('div').keyup(function(){ alert(getCaretPosition(this)); });
 div{width:300px; height:100px; border:solid 1px #DDD;} div a{background:#333; color:#FFF;}
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script> <div contenteditable=true> some example text <a>anchor tag</a>&nbsp; </div>

原始 JSFiddle: http://jsfiddle.net/wPYMR/2/

我在这里回答了一个非常相似的问题: 在IE中编辑iframe内容 - 维护文本选择的问题

这是答案的略微简化版本:

如果您没有更改contenteditable元素的内容,那么以下函数将执行。 在做任何你需要做的事之前调用saveSelection()然后再调用restoreSelection() 如果您要更改内容,我建议使用我的Rangy库的保存/恢复选择模块

var saveSelection, restoreSelection;
if (window.getSelection) {
    // IE 9 and non-IE
    saveSelection = function() {
        var sel = window.getSelection(), ranges = [];
        if (sel.rangeCount) {
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                ranges.push(sel.getRangeAt(i));
            }
        }
        return ranges;
    };

    restoreSelection = function(savedSelection) {
        var sel = window.getSelection();
        sel.removeAllRanges();
        for (var i = 0, len = savedSelection.length; i < len; ++i) {
            sel.addRange(savedSelection[i]);
        }
    };
} else if (document.selection && document.selection.createRange) {
    // IE <= 8
    saveSelection = function() {
        var sel = document.selection;
        return (sel.type != "None") ? sel.createRange() : null;
    };

    restoreSelection = function(savedSelection) {
        if (savedSelection) {
            savedSelection.select();
        }
    };
}

使用示例:

var sel = saveSelection();
// Do stuff here
restoreSelection(sel);

我发布了一个关于跨浏览器范围/选择库的问题,并发现了一些我能够解决所有需求的好东西。

这是我的帖子: 跨浏览器选择范围库?

最让我感到欣慰的是蒂姆·唐的笨拙

        var display = $("#autocomplete");
        var editArea = $('#editArea');    
        console.log(e.target.selectionStart);           
        var pos = $("#editArea").caret();
        var offset = editArea.offset();
        // now you can use left, top(they are relative position)
        display.css({
            left: offset.left + 10,
            top:  offset.top + 13,
            color : "#449"
        })
        display.toggleClass("show");
        return false;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM