Search code examples
javascriptjqueryhtmlcontenteditable

simple html editor and get html content using div or textarea


Trying to create a simple html editor.

$('#edit').on('input', function(e){
	console.log($(this).html());
});
.edit{
background:gold;
min-height:140px;
font-size:1.6em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='edit' id='edit' contenteditable></div>

type this inside the div edit:

lorem
ipsum

then place the cursor at the end of lorem - and press spacebar and del on keyboard to get this:

lorem ipsum

and you'll see the problem - ipsum has much larger font size then lorem.

That's the first question - how to avoid this?

My second try was using textarea instead of contenteditable div but in that case I cannot use document.execCommand to change some text to be bold etc.

So what is the way to set html tags inside textarea like it's done here on stackoverflow, or on wordpress sites and so on?

My final goal is to provide a simple editor with just a a few commands - bold, italic and align Users should be able to type and style the text, and click on a button should get the html content.

Any help?


Solution

  • As pointed out by many angry developers, contenteditable is indeed terrible - don't expect anything great, but let's try to make do anyway.

    By wrapping the editable div inside another div and applying the CSS font to this wrapper, the text shall not get bigger when doing the process described in the question. The HTML is still ugly (useless span tags with 1em of font size), but the text content is acceptable.

    const editable = document.querySelector('div[contenteditable]');
    
    editable.onkeyup = () => {
      document.querySelector('#html-log').innerText = editable.innerHTML;
      document.querySelector('#text-log').innerText = JSON.stringify(editable.innerText);
    }
    #wrapper {
      font-size: 1.2em;
    }
    div[contenteditable] {
      width: 100%;
      height: 100%;
      border: solid;
      font-size: 1em;
    }
    <div id="wrapper">
      <div contenteditable></div>
    </div>
    
    <h3>HTML content</h3>
    <pre id="html-log"></pre>
    
    <h3>Text content</h3>
    <pre id="text-log"></pre>