Es gibt auch ein anderes Problem.
Die Lösung von Nico Burns funktioniert, wenn das contenteditable
div keine anderen mehrzeiligen Elemente enthält.
Wenn beispielsweise ein Div andere Divs enthält und diese anderen Divs andere Inhalte enthalten, können einige Probleme auftreten.
Um sie zu lösen, habe ich die folgende Lösung zusammengestellt, die eine Verbesserung der von Nico darstellt :
(function( cursorManager ) {
var voidNodeTags = ['AREA', 'BASE', 'BR', 'COL', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR', 'BASEFONT', 'BGSOUND', 'FRAME', 'ISINDEX'];
Array.prototype.contains = function(obj) {
var i = this.length;
while (i--) {
if (this[i] === obj) {
return true;
}
}
return false;
}
function canContainText(node) {
if(node.nodeType == 1) {
return !voidNodeTags.contains(node.nodeName);
} else {
return false;
}
};
function getLastChildElement(el){
var lc = el.lastChild;
while(lc && lc.nodeType != 1) {
if(lc.previousSibling)
lc = lc.previousSibling;
else
break;
}
return lc;
}
cursorManager.setEndOfContenteditable = function(contentEditableElement)
{
while(getLastChildElement(contentEditableElement) &&
canContainText(getLastChildElement(contentEditableElement))) {
contentEditableElement = getLastChildElement(contentEditableElement);
}
var range,selection;
if(document.createRange)
{
range = document.createRange();
range.selectNodeContents(contentEditableElement);
range.collapse(false);
selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
else if(document.selection)
{
range = document.body.createTextRange();
range.moveToElementText(contentEditableElement);
range.collapse(false);
range.select();
}
}
}( window.cursorManager = window.cursorManager || {}));
Verwendung:
var editableDiv = document.getElementById("my_contentEditableDiv");
cursorManager.setEndOfContenteditable(editableDiv);
Auf diese Weise wird der Cursor sicher am Ende des letzten Elements positioniert und schließlich verschachtelt.
EDIT # 1 : Um allgemeiner zu sein, sollte die while-Anweisung auch alle anderen Tags berücksichtigen, die keinen Text enthalten können. Diese Elemente werden als ungültige Elemente bezeichnet . In dieser Frage gibt es einige Methoden zum Testen, ob ein Element ungültig ist. Angenommen, es gibt eine Funktion namens canContainText
, die zurückgibt, true
wenn das Argument kein void-Element ist, die folgende Codezeile:
contentEditableElement.lastChild.tagName.toLowerCase() != 'br'
sollte ersetzt werden durch:
canContainText(getLastChildElement(contentEditableElement))
EDIT # 2 : Der obige Code wird mit allen beschriebenen und diskutierten Änderungen vollständig aktualisiert