Search code examples
javascript

set cursor on empty tag


I'm writing text editor, with some special formatting features, using iframe in design mode. I got a problem when setting cursor position in empty element, e.g.:

<p></p>

i want to set cursor, so when user continued typing text appeared between <p> tags. Here is my code:

<iframe id="editor"></iframe>

$(document).ready(function() {
    var iframe = $('#editor').contents().get(0);
    var iwin = $('#editor')[0].contentWindow;
    iwin.document.designMode = "on";
    $('body', iframe).html('<p>ppp1</p><p></p><p>ppp3</p>');

    $('#editor').focus();
    var start = $('p', iframe)[1];

    var rng = $('#editor')[0].contentDocument.createRange();
    rng.setStart(start, 0);
    rng.setEnd(start, 0);

    var sel = iframe.getSelection();
    sel.removeAllRanges();
    sel.addRange(rng);

});

JsFiddle: http://jsfiddle.net/xbit/MGaTf/3/


Solution

  • There are a few problems here:

    • An empty paragraph doesn't render visibly in most browsers. You need some content in there;
    • You've called getSelection() on the iframe's document rather than the iframe's Window object. You need var sel = iwin.getSelection();;
    • None of this can work in IE, which has an entirely different way of handling selections.
    • WebKit cannot place the caret in a an empty element. See https://bugs.webkit.org/show_bug.cgi?id=15256

    There's a couple of other minor issues: for an iframe DOM element, contentWindow is non-standard and contentDocument is not universally supported. I'd suggest something like the following for maximum use of standards:

    var iframe = $('#editor')[0];
    var idoc, iwin;
    if (typeof iframe.contentDocument != "undefined") {
        idoc = iframe.contentDocument;
        iwin = idoc.defaultView;
    } else if (typeof iframe.contentWindow != "undefined") {
        iwin = idoc.contentWindow;
        idoc = iwin.document;
    }
    

    I've updated your example (although unfortunately the second paragraph is no longer empty): http://jsfiddle.net/timdown/MGaTf/6/