Prevent contenteditable adding <div> on ENTER - Chrome

JavascriptJqueryGoogle ChromeHtmlContenteditable

Javascript Problem Overview


I have a contenteditable element, and whenever I type some stuff and hit ENTER it creates a new <div> and places the new line text in there. I don't like this one little bit.

Is it possible to prevent this from happening or at least just replace it with a <br>?

Here is demo http://jsfiddle.net/jDvau/

Note: This is not an issue in firefox.

Javascript Solutions


Solution 1 - Javascript

Try this:

$('div[contenteditable]').keydown(function(e) {
	// trap the return key being pressed
	if (e.keyCode === 13) {
		// insert 2 br tags (if only one br tag is inserted the cursor won't go to the next line)
		document.execCommand('insertHTML', false, '<br/>');
		// prevent the default behaviour of return key pressed
		return false;
	}
});

Click here for demo

Solution 2 - Javascript

Add style display:inline-block; to contenteditable, it will not generate div, p and span automatically in Chrome.

Solution 3 - Javascript

You can do this with just a CSS change:

div{
    background: skyblue;
    padding:10px;
    display: inline-block;
}

pre{
    white-space: pre-wrap;
    background: #EEE;
}

http://jsfiddle.net/ayiem999/HW43Q/

Solution 4 - Javascript

This works in all major browsers (Chrome, Firefox, Safari, Edge)

document.addEventListener('keydown', event => {
  if (event.key === 'Enter') {
    document.execCommand('insertLineBreak')
    event.preventDefault()
  }
})

<div class="element" contenteditable="true">Sample text</div>
<p class="element" contenteditable="true">Sample text</p>

There is one inconvenience. After you finish editing, the elements might contain an ending <br> inside. But you could add code to trim that down if you need to.

Check this answer to remove the trailing <br> https://stackoverflow.com/a/61237737/670839

Solution 5 - Javascript

document.execCommand('defaultParagraphSeparator', false, 'p');
 

It overrides the default behavior to have paragraph instead.

On chrome the default behavior on enter is:

<div>
    <br>
</div>

With that command it is gonna be

<p>
    <br>
</p>

Now that it's more linear across it's easy to have only <br> would you need to.

Solution 6 - Javascript

Try this:

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

	if (event.which != 13)
		return true;

	var docFragment = document.createDocumentFragment();

	//add a new line
	var newEle = document.createTextNode('\n');
	docFragment.appendChild(newEle);

	//add the br, or p, or something else
	newEle = document.createElement('br');
	docFragment.appendChild(newEle);

	//make the br replace selection
	var range = window.getSelection().getRangeAt(0);
	range.deleteContents();
	range.insertNode(docFragment);

	//create a new range
	range = document.createRange();
	range.setStartAfter(newEle);
	range.collapse(true);

	//make the cursor there
	var sel = window.getSelection();
	sel.removeAllRanges();
	sel.addRange(range);

	return false;
});

http://jsfiddle.net/rooseve/jDvau/3/

Solution 7 - Javascript

Use shift+enter instead of enter to just put a single <br> tag in or wrap your text in <p> tags.

Solution 8 - Javascript

On the W3C Editor's Draft there are some information about adding states into ContentEditable, and to prevent the browser for adding new element when pressing enter you can use plaintext-only.

<div contentEditable="plaintext-only"></div>

Solution 9 - Javascript

The way that contenteditable behaves when you press enter depends on browsers, the <div> happens on webkit (chrome, safari) and IE.

I struggled with this few month ago and I corrected it this way :

//I recommand you trigger this in case of focus on your contenteditable
if( navigator.userAgent.indexOf("msie") > 0 || navigator.userAgent.indexOf("webkit") > 0 ) {
    //Add <br> to the end of the field for chrome and safari to allow further insertion
    if(navigator.userAgent.indexOf("webkit") > 0)
    {
        if ( !this.lastChild || this.lastChild.nodeName.toLowerCase() != "br" ) {
            $(this).html( $(this).html()+'<br />' );
        }
    }

    $(this).keypress( function(e) {
        if( ( e.keyCode || e.witch ) == 13 ) {
            e.preventDefault();

            if( navigator.userAgent.indexOf("msie") > 0 ) {
                insertHtml('<br />');
            }
            else {
              var selection = window.getSelection(),
              range = selection.getRangeAt(0),
              br = document.createElement('br');

              range.deleteContents();
              range.insertNode(br);
              range.setStartAfter(br);
              range.setEndAfter(br);
              range.collapse(false);

              selection.removeAllRanges();
              selection.addRange(range);
            }
        }
    });
}

I hope it will help, and sorry for my english if it's not as clear as needed.

EDIT : Correction of removed jQuery function jQuery.browser

Solution 10 - Javascript

You can have separate <p> tags for each line rather than using <br> tags and gain greater browser compatibility out of the box.

To do this, put a <p> tag with some default text inside of the contenteditable div.

For example, instead of:

<div contenteditable></div>

Use:

<div contenteditable>
   <p>Replace this text with something awesome!</p>
</div>

jsfiddle

Tested in Chrome, Firefox, and Edge, and the second works the same in each.

The first, however, creates divs in Chrome, creates line breaks in Firefox, and in Edge creates divs and the cursor is put back at the beginning of the current div instead of moving into the next one.

Tested in Chrome, Firefox, and Edge.

Solution 11 - Javascript

I like to use Mousetrap for handlling hotkeys: https://craig.is/killing/mice

Then, I just intercept the enter event, executing a command insertLineBreak:

Mousetrap.bindGlobal('enter', (e)=>{
  window.document.execCommand('insertLineBreak', false, null);
  e.preventDefault();
});

> All commands: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

It works using Chrome 75 and the following editable element:

<pre contenteditable="true"></pre>

It's also possible to use insertHTML:

window.document.execCommand('insertHTML', false, "\n");

Solution 12 - Javascript

I'd use styling (Css) to fix the issue.

div[contenteditable=true] > div {
  padding: 0;
} 

Firefox indeed adds a the block element break
, whereas Chrome wraps each section in a

tag. You css gives divs a padding of 10px along with the background color.

div{
  background: skyblue;
  padding:10px;
}

Alternatively, you can replicate the same desired effect in jQuery:

var style = $('<style>p[contenteditable=true] > div { padding: 0;}</style>');
$('html > head').append(style);

Here's a fork of your fiddle http://jsfiddle.net/R4Jdz/7/

Solution 13 - Javascript

The inserHTML command solution does some weird things when you have nested contenteditable elements.

I took some ideas from multiple answers here, and this seems to suit my needs for now:

element.addEventListener('keydown', function onKeyDown(e) {

	// Only listen for plain returns, without any modifier keys
	if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) {
		return;
	}

	let doc_fragment = document.createDocumentFragment();

	// Create a new break element
	let new_ele = document.createElement('br');
	doc_fragment.appendChild(new_ele);

	// Get the current selection, and make sure the content is removed (if any)
	let range = window.getSelection().getRangeAt(0);
	range.deleteContents();

	// See if the selection container has any next siblings
	// If not: add another break, otherwise the cursor won't move
	if (!hasNextSibling(range.endContainer)) {
		let extra_break = document.createElement('br');
		doc_fragment.appendChild(extra_break);
	}

	range.insertNode(doc_fragment);

	//create a new range
	range = document.createRange();
	range.setStartAfter(new_ele);
	range.collapse(true);

	//make the caret there
	let sel = window.getSelection();
	sel.removeAllRanges();
	sel.addRange(range);

	e.stopPropagation();
	e.preventDefault();

	return false;
});

// See if the given node has a next sibling.
// Either any element or a non-empty node
function hasNextSibling(node) {

	if (node.nextElementSibling) {
		return true;
	}

	while (node.nextSibling) {
		node = node.nextSibling;

		if (node.length > 0) {
			return true;
		}
	}

	return false;
}

Solution 14 - Javascript

You can wrap your paragraphs with <p> tag for example it would apper on new line instead of div Example:
<div contenteditable="true"><p>Line</p></div>
After inserting new string:
<div contenteditable="true"><p>Line</p><p>New Line</p></div>

Solution 15 - Javascript

add a prevent default to the div

document.body.div.onkeydown = function(e) {
    if ( e.keycode == 13 ){
        e.preventDefault();
            //add a <br>
        div = document.getElementById("myDiv");
        div.innerHTML += "<br>";
    }
}

Solution 16 - Javascript

Try using ckeditor. It also provide formatting like this one in SOF.

https://github.com/galetahub/ckeditor

Solution 17 - Javascript

First we need to capture every key user enter to see if enter is pressed then we prevent the <div> creation and we create our own <br> tag.

There's one problem, when we create it our cursor stay at the same position so we use Selection API to place our cursor at the end.

Don't forget to add a <br> tag at the end of your text because if you don't the first enter won't do a new line.

$('div[contenteditable]').on('keydown', function(e) {
    var key = e.keyCode,
        el  = $(this)[0];
    // If Enter    
    if (key === 13) {
        e.preventDefault(); // Prevent the <div /> creation.
        $(this).append('<br>'); // Add the <br at the end
        
        // Place selection at the end 
        // http://stackoverflow.com/questions/4233265/contenteditable-set-caret-at-the-end-of-the-text-cross-browser
        if (typeof window.getSelection != "undefined"
            && typeof document.createRange != "undefined") {
            var range = document.createRange();
            range.selectNodeContents(el);
            range.collapse(false);
            var sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (typeof document.body.createTextRange != "undefined") {
            var textRange = document.body.createTextRange();
            textRange.moveToElementText(el);
            textRange.collapse(false);
            textRange.select();
        }
    }
});

Fiddle

Solution 18 - Javascript

This is browser directed HTML5 editor. You can wrap your text with <p>...</p>, then whenever you press ENTER you get <p></p>. Also, the editor works this way that whenever you press SHIFT+ENTER it inserts <br />.

<div contenteditable="true"><p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolor veniam asperiores laudantium repudiandae doloremque sed perferendis obcaecati delectus autem perspiciatis aut excepturi et nesciunt error ad incidunt impedit quia dolores rerum animi provident dolore corporis libero sunt enim. Ad magnam omnis quidem qui voluptas ut minima similique obcaecati doloremque atque!
<br /><br />
Type some stuff, hit ENTER a few times, then press the button.
</p>
</div>

Check this: http://jsfiddle.net/ZQztJ/

Solution 19 - Javascript

if (navigator.userAgent.toLowerCase().indexOf('msie') > -1) {
   var range = document.getSelection();
   range.pasteHTML(range.htmlText + '<br><br>');
}
else if(navigator.userAgent.toLocaleLowerCase().indexOf('trident') > -1)                           {
   var range = document.getSelection().getRangeAt(0); //get caret
   var nnode = document.createElement('br');
   var bnode = document.createTextNode('\u00A0'); //&nbsp;
   range.insertNode(nnode);
   this.appendChild(bnode);
   range.insertNode(nnode);                                
}
else
   document.execCommand('insertHTML', false, '<br><br>')

Where this is the actual context which means document.getElementById('test');.

Solution 20 - Javascript

Another way to do it

$('button').click(function(){
    $('pre').text($('div')[0].outerHTML)
});

$("#content-edit").keydown(function(e) {
    if(e.which == 13) {
       $(this).find("div").prepend('<br />').contents().unwrap();
      }
});

http://jsfiddle.net/jDvau/11/

Solution 21 - Javascript

Prevent New Div creation in content editable Div on each enter key: Solution That I have find is very simple:

var newdiv = document.createElement("div"); 
newdiv.innerHTML = "Your content of div goes here";
myEditablediv.appendChild(newdiv);

This --- innerHTML content prevent New Div creation in content editable Div on each enter key.

Solution 22 - Javascript

I use hundreds of <td> elements to input calculated values and found Firefox was adding a <div></div><br /> on enter which is not cool. So I used this onkeyup:

$(document).on("keyup", '.first_td_col', function(e) {
    if (e.key === 'Enter' || e.keyCode === 13) {
       e.preventDefault();
       $(this).empty();

       return false;
    }
    // Do calculations if not enter
});

Of course this clears everything from the <td>, even the users' input. But with a message displaying No enter please., it solves unnecessary elements getting in the way of just doing the calculation.

Solution 23 - Javascript

we can clean html at end like so


function cleanHtml(innerHTML: string) {
  return innerHTML.replaceAll('<div><br></div>', '<br>')
}

in contentEditable do this

const { innerHTML, innerText } = contentEl
          console.log({ innerHTML, innerText, cleanHtml: cleanHtml(innerHTML) })

Solution 24 - Javascript

There are different solutions on the internet and most of them handle keypress same way e.g execCommand, charCode, keyCode, which. Unfortunatelly these are deprecated and non-standard features use key feature instead of these.

Also do not use contentEditable="plaintext-only" try to handle enter keypress and insert br note to current selection.

Check my solution below it's working without any issue in Chrome, Firefox, Opera and Edge.

function handleEnterPress(e) {
  if (e.key.toLowerCase() === 'enter') {
    e.preventDefault();
    let selection = window.getSelection();
    let range = selection.getRangeAt(0);
    range.insertNode(document.createElement('br'));
    selection.collapseToEnd();
  }
  return false;
}

function handleEnterPress(e) {
  if (e.key.toLowerCase() === 'enter') {
    e.preventDefault();
    let selection = window.getSelection();
    let range = selection.getRangeAt(0);
    range.insertNode(document.createElement('br'));
    selection.collapseToEnd();
  }
  return false;
}

div[contenteditable="true"] {
  background-color: bisque;
  padding: 80px;
  border: 1px solid black;
}

<div contenteditable="true" onkeypress="handleEnterPress(event)">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</div>

Solution 25 - Javascript

It is possible to prevent this behaviour entirely.

See this fiddle

$('<div class="temp-contenteditable-el" contenteditable="true"></div>').appendTo('body').focus().remove();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioniConnorView Question on Stackoverflow
Solution 1 - JavascriptRam G AthreyaView Answer on Stackoverflow
Solution 2 - JavascriptLe Tung AnhView Answer on Stackoverflow
Solution 3 - JavascriptairiView Answer on Stackoverflow
Solution 4 - Javascriptuser670839View Answer on Stackoverflow
Solution 5 - JavascriptCedView Answer on Stackoverflow
Solution 6 - JavascriptAndrewView Answer on Stackoverflow
Solution 7 - JavascriptBlake PlumbView Answer on Stackoverflow
Solution 8 - JavascriptStefansAryaView Answer on Stackoverflow
Solution 9 - JavascriptElieView Answer on Stackoverflow
Solution 10 - JavascriptJosh PowlisonView Answer on Stackoverflow
Solution 11 - JavascriptGaussView Answer on Stackoverflow
Solution 12 - JavascriptcbayramView Answer on Stackoverflow
Solution 13 - JavascriptskeritView Answer on Stackoverflow
Solution 14 - JavascriptnesView Answer on Stackoverflow
Solution 15 - JavascriptMath chillerView Answer on Stackoverflow
Solution 16 - JavascriptDan Rey OquindoView Answer on Stackoverflow
Solution 17 - JavascriptL105View Answer on Stackoverflow
Solution 18 - JavascriptMehdiView Answer on Stackoverflow
Solution 19 - JavascriptwebprogrammerView Answer on Stackoverflow
Solution 20 - JavascriptMrAJView Answer on Stackoverflow
Solution 21 - JavascriptDrShyam Babu GuptaView Answer on Stackoverflow
Solution 22 - JavascriptHmerman6006View Answer on Stackoverflow
Solution 23 - JavascriptChetan JainView Answer on Stackoverflow
Solution 24 - Javascripterman999View Answer on Stackoverflow
Solution 25 - JavascriptOmniconView Answer on Stackoverflow