简体   繁体   English

在可内容编辑的DIV中获得插入符HTML位置

[英]Get caret HTML position in contenteditable DIV

I am having troubles figuring out how to get caret position in a DIV container that contains HTML tags. 我在弄清楚如何在包含HTML标签的DIV容器中获得插入符位置时遇到麻烦。

I am using this JavaScript function to do that: 我正在使用此JavaScript函数来做到这一点:

function  getCaretPosition()
{
    if (window.getSelection && window.getSelection().getRangeAt)
    {
            var range = window.getSelection().getRangeAt(0);
            var selectedObj = window.getSelection();
            var rangeCount = 0;
            var childNodes = selectedObj.anchorNode.parentNode.childNodes;
            for (var i = 0; i < childNodes.length; i++)
            {
                if (childNodes[i] == selectedObj.anchorNode)
                {
                        break;
                    }
                        if(childNodes[i].outerHTML)
                        {
                rangeCount += childNodes[i].outerHTML.length;
            }
            else if(childNodes[i].nodeType == 3)
            {
                            rangeCount += childNodes[i].textContent.length;                       
            }
        }
        return range.startOffset + rangeCount;
    }
    return -1;
}

However, it finds a caret position of the text in my DIV container, when I need to find the caret position including HTML tags. 但是,当我需要找到包含HTML标记的插入位置时,它将在DIV容器中找到文本的插入位置。 For example: 例如:

<DIV class="peCont" contenteditable="true">Text goes here along with <b>some <i>HTML</i> tags</b>.</DIV>;

( please note, that HTML tags are normal tags and are not displayed on the screen when the function is returning caret position ) 请注意,HTML标签是普通标签,当函数返回插入符号位置时,它们不会显示在屏幕上

If I click right between H and TML, the aforementioned function will find caret position without any problems. 如果在H和TML之间单击鼠标右键,上述功能将找到插入符位置,而不会出现任何问题。 But I am getting the contents of DIV box in HTML format (including all tags), and if I want to insert something at that caret's position, I will be off by a few or many characters. 但是我得到的是HTML格式的DIV框的内容(包括所有标签),如果我想在插入符号的位置插入一些内容,我将失去几个或多个字符。

I went through many posts, but all I could find is either <TEXTAREA> caret postions, or functions similar to what I have posted. 我浏览了许多帖子,但是我只能找到<TEXTAREA>插入符号位置,或类似于我发布的功能。 So far I still cannot find a solution to get a caret position in a text that has HTML formatting. 到目前为止,我仍然找不到在具有HTML格式的文本中获得插入符号位置的解决方案。

Can anyone help, please? 有人可以帮忙吗?

PS. PS。 Here's JQuery/Javascript code that I wrote for the link button: 这是我为链接按钮编写的JQuery / Javascript代码:

$('#pageEditor').on('click', '.linkURL', function()
{
    var cursorPosition;
    cursorPosition = getCaretPosition();
    var contentID = $(this).parent().parent().attr('id');
    var userSelected = getSelectionHtml();
    var checkLink = userSelected.search('</a>');
    var anchorTag = 0;
    if(checkLink == -1)
    {
        var currentContents = $('#'+contentID+' .peCont').html();
        var indexOfSelection = currentContents.indexOf(userSelected);
        var getPossibleAnchor = currentContents.slice(indexOfSelection, indexOfSelection+userSelected.length+6);
        anchorTag = getPossibleAnchor.search('</a>');
    }

    if(checkLink > 0 || anchorTag > 0)
    {
        //alert(checkLink);
        document.execCommand('unlink', false, false);

    }
    else
    {
        $('#'+contentID+' .peCont').append('<div id="linkEntry"><label for="urlLink">Please enter URL for the link:<label><input type="text" id="urlLink" /></div>');
        $('#linkEntry').dialog({
             buttons: { 
                "Ok": function() 
                {
                    var attribute = $('#urlLink').val();
                    var newContentWithLink = '';
                    if(attribute != '')
                    {
                        if(userSelected != '')
                        {
                            var currentContent = $('#'+contentID+' .peCont').html();
                            var replacement = '<a href="'+attribute+'">'+userSelected+'</a>';
                            newContentWithLink = currentContent.replace(userSelected, replacement);
                        }
                        else
                        {
                            var currentTextContent = $('#'+contentID+' .peCont').html();
                            var userLink = '<a href="'+attribute+'">'+attribute+'</a>';
                            if(cursorPosition > 0)
                            {
                                var contentBegin = currentTextContent.slice(0,cursorPosition);
                                var contentEnd = currentTextContent.slice(cursorPosition,currentTextContent.length);
                                newContentWithLink = contentBegin+userLink+contentEnd;
                            }
                            else
                            {
                                newContentWithLink = attribute+currentTextContent;
                            }
                        }
                        $('#'+contentID+' .peCont').empty();
                        $('#'+contentID+' .peCont').html(newContentWithLink);
                    }
                    $(this).dialog("close"); 
                } },
             closeOnEscape:true,
             modal:true,
             resizable:false,
             show: { effect: 'drop', direction: "up" },
             hide: { effect: 'drop', direction: "down" },
             width:460,
             closeText:'hide',
             close: function()
             {
                $(this).remove();
             }
        });

        $('#linkEntry').on('keypress', function(urlEnter)
        {
            if(urlEnter.which == 13)
            {
                var attribute = $('#urlLink').val();
                var newContentWithLink = '';
                if(userSelected != '')
                {
                    var currentContent = $('#'+contentID+' .peCont').html();
                    var replacement = '<a href="'+attribute+'">'+userSelected+'</a>';
                    newContentWithLink = currentContent.replace(userSelected, replacement);
                }
                else
                {
                    var currentTextContent = $('#'+contentID+' .peCont').html();
                    var userLink = '<a href="'+attribute+'">'+attribute+'</a>';
                    if(cursorPosition > 0)
                    {
                        var contentBegin = currentTextContent.slice(0,cursorPosition);
                        var contentEnd = currentTextContent.slice(cursorPosition,currentTextContent.length);
                        newContentWithLink = contentBegin+userLink+contentEnd;
                    }
                    else
                    {
                        newContentWithLink = attribute+currentTextContent;
                    }
                }
                $('#'+contentID+' .peCont').empty();
                $('#'+contentID+' .peCont').html(newContentWithLink);
                $(this).dialog("close");
            }
        });
    }
});

I created a simple fiddle for you that does what you want. 我为您创建了一个简单的小提琴可以满足您的需求。

This should work in recent versions of Firefox, Chrome and Safari. 在最新版本的Firefox,Chrome和Safari中应该可以使用。

It's your homework to add Opera and IE support if you need. 如果需要,添加Opera和IE支持是您的家庭作业。

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

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