Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There is also another problem.</p> <p>The <a href="https://stackoverflow.com/users/140293/nico-burns">Nico Burns</a>'s solution works if the <code>contenteditable</code> div doesn't contain other multilined elements.</p> <p>For instance, if a div contains other divs, and these other divs contain other stuff inside, could occur some problems.</p> <p>In order to solve them, I've arranged the following solution, that is an improvement of the <a href="https://stackoverflow.com/users/140293/nico-burns">Nico</a>'s one:</p> <pre><code>//Namespace management idea from http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/ (function( cursorManager ) { //From: http://www.w3.org/TR/html-markup/syntax.html#syntax-elements var voidNodeTags = ['AREA', 'BASE', 'BR', 'COL', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR', 'BASEFONT', 'BGSOUND', 'FRAME', 'ISINDEX']; //From: https://stackoverflow.com/questions/237104/array-containsobj-in-javascript Array.prototype.contains = function(obj) { var i = this.length; while (i--) { if (this[i] === obj) { return true; } } return false; } //Basic idea from: https://stackoverflow.com/questions/19790442/test-if-an-element-can-contain-text function canContainText(node) { if(node.nodeType == 1) { //is an element node return !voidNodeTags.contains(node.nodeName); } else { //is not an element node return false; } }; function getLastChildElement(el){ var lc = el.lastChild; while(lc &amp;&amp; lc.nodeType != 1) { if(lc.previousSibling) lc = lc.previousSibling; else break; } return lc; } //Based on Nico Burns's answer cursorManager.setEndOfContenteditable = function(contentEditableElement) { while(getLastChildElement(contentEditableElement) &amp;&amp; canContainText(getLastChildElement(contentEditableElement))) { contentEditableElement = getLastChildElement(contentEditableElement); } var range,selection; if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+ { range = document.createRange();//Create a range (a range is a like the selection but invisible) range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start selection = window.getSelection();//get the selection object (allows you to change selection) selection.removeAllRanges();//remove any selections already made selection.addRange(range);//make the range you have just created the visible selection } else if(document.selection)//IE 8 and lower { range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible) range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start range.select();//Select the range (make it the visible selection } } }( window.cursorManager = window.cursorManager || {})); </code></pre> <p>Usage:</p> <pre><code>var editableDiv = document.getElementById("my_contentEditableDiv"); cursorManager.setEndOfContenteditable(editableDiv); </code></pre> <p>In this way, the cursor is surely positioned at the end of the last element, eventually nested.</p> <p><strong>EDIT #1</strong>: In order to be more generic, the while statement should consider also all the other tags which cannot contain text. These elements are named <em>void elements</em>, and in <a href="https://stackoverflow.com/questions/19790442/test-if-an-element-can-contain-text">this question</a> there are some methods on how to test if an element is void. So, assuming that exists a function called <code>canContainText</code> that returns <code>true</code> if the argument is not a void element, the following line of code:</p> <pre><code>contentEditableElement.lastChild.tagName.toLowerCase() != 'br' </code></pre> <p>should be replaced with:</p> <pre><code>canContainText(getLastChildElement(contentEditableElement)) </code></pre> <p><strong>EDIT #2</strong>: The above code is fully updated, with every changes described and discussed</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload