Intro
When editing the content of a contenteditable DOM Object, different browsers have different behaviours. For instance, Firefox 18.0 creates a new paragraph (<p>
) or a line break <br/>
in some instances while Chrome 24 creates a <div>
.
In order to cope with this, I'm listening to the DOMNodeInserted
event and replacing the new inserted nodes with p tags.
Problem
The problem is placing the caret in place. I've read tons of posts in SO regarding this same subject but none of the provided answers have worked, at least in Chrome 24.
Code
obj.addEventListener("DOMNodeInserted", onNodeInsert, false);
function onNodeInsert(e) {
var range = document.createRange(),
sel = window.getSelection(),
newNode = e.target,
tagName = newNode.tagName.toLowerCase(),
lnbrNode = document.createElement('br'),
pNode = document.createElement('p');
if (tagName === 'div' && newNode.getAttribute("id") === null) {
// First we remove the event listener so that it doesn't get triggered again
this.removeEventListener('DOMNodeInserted', onNodeInsert, false);
// Creates a p node and removes the div
newNode.parentNode.replaceChild(pNode, newNode);
pNode.appendChild(lnbrNode);
// Places the caret where it belongs
range.setStart(pNode, 0);
sel.removeAllRanges();
sel.addRange(range);
//We can restore the event listener now
this.addEventListener("DOMNodeInserted", onNodeInsert, false);
}
}
U+200B
), either by adding a new text node or inserting into an existing one, at the position you wish to place the caret and then place the caret immediately after this zero-width space. The user will not see the difference (unless they use the left arrow key). You then have the problem of removing this space afterwards when it's no longer necessary. – Yellowlegs