Set cursor after span element inside contenteditab

2020-01-31 07:33发布

How can I set the cursor after a span element inside an contenteditable div? Right now, I've an image inside a span element, inside the contenteditable div.

When I add some characters, they are added inside the span, but I want them to be added after the span element. Any ideas how I can achieve this?

4条回答
我欲成王,谁敢阻挡
2楼-- · 2020-01-31 08:08

In browsers other than IE <= 8, this will do it:

function placeCaretAfterNode(node) {
    if (typeof window.getSelection != "undefined") {
        var range = document.createRange();
        range.setStartAfter(node);
        range.collapse(true);
        var selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
    }
}

However, some browsers (notably WebKit-based ones) have fixed ideas about which positions in the document are valid for the caret and will normalize any range you add to the selection to comply with those ideas. The following example will do what you want in Firefox and IE 9 but not in Chrome or Safari as a result:

http://jsfiddle.net/5dxwx/

None of the workarounds are good. Options include:

  • add a zero-width space character after the span and select it
  • use an <a> element instead of a <span> because WebKit makes an exception for <a> elements
查看更多
迷人小祖宗
3楼-- · 2020-01-31 08:08

I managed to solve this problem using 'a' tag with &nbsp. Example :- "<a>"+ content/element you want to add +"</a>&nbsp;"

查看更多
一纸荒年 Trace。
4楼-- · 2020-01-31 08:28

This function manages what I had in mind:

<script type="text/javascript">
function pasteHtmlAtCaret(char) {
        var sel = rangy.getSelection();
        var range = sel.rangeCount ? sel.getRangeAt(0) : null;
        var parent;
        if (range) {
            var parentEl = document.createElement("span");
        jQuery(parentEl).addClass('char').addClass('latest');
            parentEl.appendChild(range.createContextualFragment(char));

            // Check if the cursor is at the end of the text in an existing span
            if (range.endContainer.nodeType == 3
            && (parent = range.endContainer.parentNode)
            && (parent.tagName == "SPAN")) {
            range.setStartAfter(parent);
            }
            range.insertNode(parentEl);
        if(jQuery(parentEl).parent().get(0).tagName.toLowerCase() == 'span'){
            var spanParent = jQuery(parentEl).parent('span');
            var parentEl = jQuery('<span class="char latest spanchild"></span>').insertAfter(spanParent).append(parentEl).get(0);
        }
        jQuery("span.spanchild").each(function(index, element){
            var content = jQuery(element).children('span.char').first().html();
            jQuery(element).children('span.char').remove();
            jQuery(element).html(content);
            jQuery(element).removeClass('spanchild');
        });
            range.setStartAfter(parentEl);
            rangy.getSelection().setSingleRange(range);
        jQuery(parentEl).removeClass('latest');
        }
}
</script>
查看更多
冷血范
5楼-- · 2020-01-31 08:29

Just span.contentEditable = false to Tim's solution work properly ;)

查看更多
登录 后发表回答