2010-11-20 10 views
79

Ausgang in Chrome:contenteditable, setzen caret am Ende des Textes (Cross-Browser)

<div id="content" contenteditable="true" style="border:1px solid #000;width:500px;height:40px;"> 
    hey 
    <div>what's up?</div> 
<div> 
<button id="insert_caret"></button> 

Ich glaube an FF es in etwa so aussehen würde:

hey 
<br /> 
what's up? 

und in IE:

hey 
<p>what's up?</p> 

Leider gibt es keine gute Möglichkeit, es so zu machen, dass jeder Browser anstelle eines div- oder p-Tags eine <br /> einfügt, oder zumindest konnte ich nichts online finden.


wie auch immer, was ich jetzt versuchen zu tun ist, wenn ich traf die Taste, mag ich die Einfügemarke am Ende des Textes festgelegt werden, so sollte es in etwa so aussehen:

jeder weg dies zu tun, so funktioniert es in alle browser?

Beispiel:

$(document).ready(function() 
{ 
    $('#insert_caret').click(function() 
    { 
     var ele = $('#content'); 
     var length = ele.html().length; 

     ele.focus(); 

     //set caret -> end pos 
    } 
} 

Antwort

213

Die folgende Funktion ist es in allen gängigen Browsern tun:

function placeCaretAtEnd(el) { 
    el.focus(); 
    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(); 
    } 
} 

placeCaretAtEnd(document.getElementById("content")); 

die Einfügemarke am Anfang zu setzen ist fast identisch: Es erfordert nur die Boolesche in den übergebenen Wechsel Anrufe an collapse(). Hier ist ein Beispiel, das Funktionen für die Platzierung der caret am Anfang und am Ende schafft:

function createCaretPlacer(atStart) { 
    return function(el) { 
     el.focus(); 
     if (typeof window.getSelection != "undefined" 
       && typeof document.createRange != "undefined") { 
      var range = document.createRange(); 
      range.selectNodeContents(el); 
      range.collapse(atStart); 
      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(atStart); 
      textRange.select(); 
     } 
    }; 
} 

var placeCaretAtStart = createCaretPlacer(true); 
var placeCaretAtEnd = createCaretPlacer(false); 
+0

Funktioniert nicht mit Chrome, da CreateTextRange keine Standardfunktion ist. Siehe https://stackoverflow.com/a/41743191/700206. – Lee

+0

@Lee: Es funktioniert gut in Chrome, die 'window.getSelection' und' document.createRange' unterstützt. Der 'createTextRange'-Zweig ist für alte Versionen von Internet Explorer. –

+0

zum Zeitpunkt des Schreibens 'window.getSelection' wird nicht von 0,29% aller Browser unterstützt (IE> 8). siehe: http://caniuse.com/#search=window.getSelection – Silentdrummer

-2

Wenn Sie den Google-Verschluss-Compiler verwenden, können Sie folgendes tun (etwas von Tim Antwort vereinfacht):

function placeCaretAtEnd(el) { 
    el.focus(); 
    range = goog.dom.Range.createFromNodeContents(el); 
    range.collapse(false); 
    range.select(); 
} 

Hier ist die gleiche Sache in ClojureScript:

(defn place-caret-at-end [el] 
    (.focus el) 
    (doto (.createFromNodeContents goog.dom.Range el) 
     (.collapse false) 
     .select)) 

ich das getestet habe in Chrome, Safari und FireFox, nicht sicher IE ...

+0

Bereich = goog.dom.Range.createFromNodeContents (el); Was ist goog.dom? –

2

Leider funktionierte Tims ausgezeichnete Antwort nur für mich am Ende, für die Platzierung am Anfang musste ich sie etwas modifizieren.

function setCaret(target, isStart) { 
    const range = document.createRange(); 
    const sel = window.getSelection(); 
    if (isStart){ 
    const newText = document.createTextNode(''); 
    target.appendChild(newText); 
    range.setStart(target.childNodes[0], 0); 
    } 
    else { 
    range.selectNodeContents(target); 
    } 
    range.collapse(isStart); 
    sel.removeAllRanges(); 
    sel.addRange(range); 
    target.focus(); 
    target.select(); 
} 

Nicht sicher, obwohl, wenn focus() und select() sind tatsächlich benötigt wird.

+0

Sie haben auch eine externe Bibliothek eingeführt. Wenn Sie nicht denken, Fokus und Auswahl ist erforderlich, warum nicht die Zeilen auskommentieren und testen? – dotnethaggis

+0

Danke, jquery entfernt. Ich erinnere mich, dass ich widersprüchliche Ergebnisse hatte, ich werde versuchen, sie wieder zu isolieren. – dimid

Verwandte Themen