简体   繁体   English

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

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

I am working with a contenteditable div that will have the option to have inline html elements such as tags in the text flow.我正在使用一个 contenteditable div,它可以选择在文本流中包含内联 html 元素,例如标签。

At certain points I need to grab the caret position but have found that with the example code the position returned is incorrect if the caret is after an html child element.在某些时候,我需要获取插入符 position,但发现如果插入符位于 html 子元素之后,则使用示例代码返回的 position 是不正确的。

I need a cross browser solution that will allow me to store the position of the caret so that it can be restored a split second later even with the presence of html elements in the text flow.我需要一个跨浏览器解决方案,它允许我存储插入符号的 position,以便即使在文本流中存在 html 元素的情况下也可以稍后恢复它。

Example:例子:

 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>

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

I've answered a very similar question here: Editing Iframe Content in IE - problem in maintaining text selection 我在这里回答了一个非常相似的问题: 在IE中编辑iframe内容 - 维护文本选择的问题

Here's a slightly simplified version of that answer: 这是答案的略微简化版本:

If you're not changing the contents of the contenteditable element then the following functions will do. 如果您没有更改contenteditable元素的内容,那么以下函数将执行。 Call saveSelection() before doing whatever you need to do and restoreSelection() afterwards. 在做任何你需要做的事之前调用saveSelection()然后再调用restoreSelection() If you are changing the content, I'd suggest using my Rangy library's save/restore selection module . 如果您要更改内容,我建议使用我的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();
        }
    };
}

Example use: 使用示例:

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

I posted a question about a cross-browser range/selection library and found some great stuff that I was able to solve all my needs with. 我发布了一个关于跨浏览器范围/选择库的问题,并发现了一些我能够解决所有需求的好东西。

Here is my post: Cross Browser Selection Range Library? 这是我的帖子: 跨浏览器选择范围库?

What helped me best was Tim Down's rangy . 最让我感到欣慰的是蒂姆·唐的笨拙

        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.

相关问题 如何在Internet Explorer中使用html子元素在contenteditable div中获取插入位置 - How to get caret position within contenteditable div with html child elements in Internet Explorer 在可内容编辑的DIV中获得插入符HTML位置 - Get caret HTML position in contenteditable DIV 如何在忽略HTML标签的情况下将插入符号放置在contenteditable div中? - How to position a caret in a contenteditable div while ignoring the HTML tags? HTML节点位于contenteditable中的插入符位置<div> - HTML node at caret position in contenteditable <div> 如何获得包含图像的contenteditable div的插入位置 - how to get the caret position of a contenteditable div which contains images 如何在 contentEditable div 中获取插入符号 x 和 y 位置 - How to get caret x and y position in contentEditable div 如何获取 ContentEditable 元素中关于innerText 的插入符号位置? - How to get the caret position in ContentEditable elements with respect to the innerText? h如何获得 contentEditable div 的插入符号位置? - hHow to get caret position for contentEditable div? 获取内容Editable caret position - Get contentEditable caret position 使用textangular在可编辑内容的div中记录和恢复插入符号的位置 - Recording and restoring the position of the caret within a contenteditable div using textangular
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM