How to create a paragraph on enter in a contentedi

2019-04-08 23:00发布

问题:

I'm making a simple editor for a project of mine, where I need to use an editable div using contenteditable property. I need two features:

  • Auto insert hr after two enters
  • Create a paragraph instead of <br> on enter and focus on it.

So I wrote this (with some inspiration), this is part of the code that is responsible:

var intercept = {
    keydown: function(e)
    {
        if( e.which == 13 ){
            intercept.enterKey.call(null, e);
        }
    },

    enterKey: function(e)
    {
        var $lastElm;

        // Find the previous elm
        if (document.selection) { // IE
            $lastElm = $(document.selection.createRange().parentElement());
        } else { // everyone else
            $lastElm = $(window.getSelection().anchorNode);
        }

        // Handle enter key
        if( !e.shiftKey )
        {
            // Check if two or more paragraphs
            // are empty, so we can add an hr
            if(
                $.trim($lastElm.text()) === "" &&
                !$lastElm.prev().is('hr')
            ){
                document.execCommand('insertParagraph', false);
                $lastElm.replaceWith($('<hr>', {contenteditable: false}));
            }
            // Or just add an paragraph
            else{
                document.execCommand('insertParagraph', false, true);
            }

            e.preventDefault();
        }
    }
}

This works fine in Chrome, but in Firefox, it doesnt create a new <p> element, I think it just wraps the current text in a p which isn't possible because it's already in a p. So the cursor just stays there in firefox and new paragraph isn't created.

Do you have an idea how to fix this?
Thanks.

回答1:

From Jquery you can use this method:

var html="";
var intercept = {
    keydown: function(e)
    {
        if( e.which == 13 ){
            intercept.enterKey.call(null, e);
        }
    },

    enterKey: function(e)
    {
        $("#append_id").html("");
        html+="your text";
        $("#append_id").html("<p>"+html+"</p>");
    }
}


回答2:

I did something which completely based on JQuery:

var debug=0;
$(function (){
    $(".test").on('blur keyup paste focus focusout',function (){
        if($(".test").children().size()==0)
        {
            if(debug) console.log("add p");
            //Only Test now
            var text=$(".test").text();
            $(".test").empty();
            $(".test").append("<p>"+text+"</p>");
        }

        if(debug) console.log("-------------------------");
        if(debug) console.log($(".test").children());
        for(var i=0;i<$(".test").children().size();i++)
        {
            var tag=$(".test").children().eq(i).prop("tagName").toLowerCase();
            console.log("i="+i+" ["+tag+"]");
            if(i%3==2)
            {
                if($(".test").children().size()==i+1 && $(".test").children().last().text()=="")
                    continue;

                if(tag!="hr")
                {
                    if(debug) console.log("  add hr");
                    $(".test").children().eq(i).before("<hr/>")    
                }
            }
            else if(tag=="hr")
            {
                if(debug) console.log("  rm hr");
                $(".test").children().get(i).remove();
            }
            else if(tag=="br")
            {
                if(debug) console.log("  br");
                $(".test").children().eq(i).remove();
                var text=$(".test").children().size>=i?$(".test").children().eq(i+1).text():"";
                $(".test").children().eq(i).after($("<p>"+text +"</p>"));
                $(".test").children().eq(i).append("<p>"+text+"</p>");
                if($(".test").children().size>=i+1) 
                    $(".test").children().eq(i+1).remove();    
            }
            else if (tag!="p")
            {
                if(debug) console.log("  not p");
                var text=$(".test").children().eq(i).text();
                $(".test").children().eq(i).remove();
                $(".test").children().eq(i).after($("<p>"+text +"</p>"));
            }

        }

    });

http://jsfiddle.net/aj33Q/14/

Hope this helps!