Set caret after creating new element in contenteditable div

I have a contenteditable div that has elements within it. What I want to happen is for a new paragraph tag to be created immediately after the element that the caret is currently in when the enter key is pressed. I can create the paragraph tag when I press enter, but I want the caret to be placed at the end of the text of the paragraph tag right before the closing </p>

Here's a demo:

http://jsfiddle.net/qcf4d/1/

$(document).on('keypress', 'div[contenteditable="true"]', function(event) {


  //enter key
  if (event.which == 13) {
    //insert the paragraph after this element.
    $(window.getSelection().anchorNode.parentNode).after("<p>cool</p>");
  }

});

Thoughts? I think the jquery focus() function will come in handy.


There's a glitch: the first "cool" always gets the cursor, because you're getting it by "id". To avoid that problem I'm creating a <p>cool</p> element before appending it, then using that to locate the new cursor position.

$(document).on('keypress', 'div[contenteditable="true"]', function(event) {

    if (event.which == 13) { // enter key
        event.preventDefault();

        //insert the paragraph after this element.
        var innerDiv = $("<p>cool</p>")
        var sel = window.getSelection()
        $(sel.anchorNode.parentNode).after(innerDiv);

        //set cursor at new position
        sel.collapse(innerDiv[0].firstChild, innerDiv.text().length);
    }    
});

JSFiddle

And a no-jQ version:

document.querySelector('div[contenteditable="true"]').addEventListener('keypress', function(event) {

    if (event.which == 13) { // enter key
        event.preventDefault();

        //insert the paragraph after this element.
        var innerDiv = document.createElement('p')
        innerDiv.innerHTML = 'cool'
        var sel = window.getSelection()
        var selElem = sel.anchorNode.parentNode
        selElem.parentNode.insertBefore(innerDiv, selElem.nextSibling)

        //set cursor at new position
        sel.collapse(innerDiv.firstChild, innerDiv.textContent.length);
    }
});

JSFiddle no-jQ


I found out the solution. You can get the new paragraph by its ID and then set the caret at the length of the text in that paragraph:

$(document).on('keypress', 'div[contenteditable="true"]', function(event) {


//enter key
if (event.which == 13) {
    event.preventDefault();
    //insert the paragraph after this element.
    $(window.getSelection().anchorNode.parentNode).after("<p id='newParagraph'>cool</p>");

    //set cursor at new position
    var sel = window.getSelection();
    var innerDiv = document.getElementById('newParagraph');
    var innerDivText = innerDiv.firstChild;

    returnFocus = $("#newParagraph").text().length;
    sel.collapse(innerDivText, returnFocus);
    innerDiv.parentNode.focus();

}

});

http://jsfiddle.net/qcf4d/2/

If anyone has a more efficient (or jQuery) way of doing this let me know.

链接地址: http://www.djcxy.com/p/74328.html

上一篇: Contenteditable setCursorPos(elem,pos),pos = getCursorPos(elem)

下一篇: 在contenteditable div中创建新元素后设置插入符号