2015-12-04 15 views
16

Ich habe einen contenteditable div die Ich mag wäre in der Lage sein, Benutzer zu haben, Dinge einfügen wie Links, Bilder oder Videos von YouTube. Im Moment ist es das, was ich habe:Setzt und Cursorposition mit contenteditable div

function addLink() { 
 
    var link = $('#url').val(); 
 
    $('#editor').focus(); 
 
    document.execCommand('createLink', false, link); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<!-- Text Editor --> 
 
<div id="editor" contenteditable="true"></div> 
 

 
<!-- Add Link --> 
 
<input type="text" id="url"> 
 
<button onclick="addLink()">Submit</button>

Wie Sie sehen können, hat der Benutzer in einem separaten Textfeld geben Sie den Link-Adresse einzugeben. Als Ergebnis, wenn die Verbindung zum Editor hinzugefügt wird, wird es nicht in die Position hinzugefügt, dass die Zeiger/caret eingeschaltet ist.

Meine Frage ist, wie ich die Position des Zeigers/caret erhalten und einstellen können. Ich habe andere Fragen wie this for setting the pointer gesehen, aber ich würde lieber eine Lösung haben, die in allen modernen Browsern unterstützt wird, einschließlich Chrome, Safari, Firefox und IE9 +.

Irgendwelche Ideen? Vielen Dank.

Edit:

fand ich den Code unter dem jedoch die Position kommt, es wird nur die Position entsprechend der Linie es eingeschaltet ist. Zum Beispiel, wenn ich dies hatte (wo | ist der Cursor):

This is some text 
And som|e more text 

Dann würde ich den Wert 7, 24.

function getPosition() { 
    if (window.getSelection) { 
     sel = window.getSelection(); 
     if (sel.getRangeAt) { 
      return sel.getRangeAt(0).startOffset; 
     } 
    } 
    return null; 
} 
+0

Die Lösung, die Sie verknüpft haben, hat eine Lösung, die auf allen Browsern funktioniert, lesen Sie einfach über die akzeptierte hinaus. Wie zum Abrufen der Cursorposition versuchen Sie dies: http://stackoverflow.com/questions/4767848/get-caret-cursor-position-in-contenteditable-area-containt-html-content – SunKnight0

+0

@ SunKnight0 Ich habe den folgenden Code aus dem versucht Lösung, die Sie jedoch zurückgegeben haben, wie immer 0. 'var editor = document.getElementById ('# editor');' 'console.log (getCaretCharacterOffsetWithin (editor));' Ich habe die Funktion aus dieser Antwort http: // stack overflow verwendet .com/questions/4811822/get-a-ranges-start-und-end-offsets-relativ-zu-ihm-eltern-container/4812022 # 4812022 –

+0

Verwenden Sie 'getElementById ('editor')'. Sie mischen Vanilla JavaScript mit JQuery. – SunKnight0

Antwort

3

ein guter Rich-Text-Editor eine der schwierigeren Dinge ist zur Zeit zu tun, und ist so ziemlich ein Projekt von selbst (unfreundlicher API, riesige Anzahl von Eckfällen , Cross-Browser-Unterschiede, die Liste geht weiter). Ich würde empfehlen Ihnen dringend, um zu versuchen und eine vorhandene Lösung zu finden.

Einige Bibliotheken, die verwendet werden können, gehören:

+0

Danke für Ihre Antwort, aber ich möchte einen einfachen Texteditor und nicht einen Code-Editor wie Code-Spiegel. –

+1

Danke für das Hinzufügen von Quill und WYSIHTML. Diese scheinen viel besser zu dem zu passen, was Sie in der Frage beschrieben haben. – SpeedySan

6

Es gibt eine Tonne von verwandten Informationen nicht vor Ort zurückgegeben werden. Dieser funktioniert für mich und meine Kunden.

DEMO

https://stackoverflow.com/a/6249440/2813224

function setCaret(line, col) { 
 
    var ele = document.getElementById("editable"); 
 
    var rng = document.createRange(); 
 
    var sel = window.getSelection(); 
 
    rng.setStart(ele.childNodes[line], col); 
 
    rng.collapse(true); 
 
    sel.removeAllRanges(); 
 
    sel.addRange(range); 
 
    ele.focus(); 
 
} 
 

 
//https://stackoverflow.com/a/6249440/2813224 
 

 
var line = document.getElementById('ln').value; 
 
var col = document.getElementById('cl').value; 
 
var btn = document.getElementById('btn'); 
 
btn.addEventListener('click', function(event) { 
 
    var lineSet = parseInt(line, 10); 
 
    var colSet = parseInt(col, 10); 
 
    setCaret(lineSet, colSet); 
 
}, true);
<div id="editable" contenteditable="true"> 
 
    <br/>text text text text text text 
 
    <br/>text text text text text text 
 
    <br/>text text text text text text 
 
    <br/> 
 
    <br/> 
 
</div> 
 
<fieldset> 
 
    <button id="btn">focus</button> 
 
    <input type="button" class="fontStyle" onclick="document.execCommand('italic',false,null);" value="I" title="Italicize Highlighted Text"> 
 
    <input type="button" class="fontStyle" onclick="document.execCommand('bold',false,null);" value="B" title="Bold Highlighted Text"> 
 
    <input id="ln" placeholder="Line#" /> 
 
    <input id="cl" placeholder="Column#" /> 
 
</fieldset>

2

Ich habe versucht, eine Lösung zu finden,

Mit einer wenig Hilfe kann es perfektioniert werden. Es ist eine Kombination von Antworten, die ich auf SO gefunden habe, und meine exp.

Sein tricky, seine chaotisch ... aber wenn es sein muss, können Sie es verwenden, aber es erfordert ein wenig Arbeit inneren Verbindungen zu unterstützen (wenn Sie auf einem Anker Cursor ist es Anker innerhalb Anker schaffen)

Hier ist der JS:

var lastPos; 
var curNode = 0; 
function setCaret() { 
    curNode=0; 
    var el = document.getElementById("editor"); 
    var range = document.createRange(); 
    var sel = window.getSelection(); 

    console.log(el.childNodes); 
    if (el.childNodes.length > 0) { 
     while (lastPos > el.childNodes[curNode].childNodes[0].textContent.length) { 
     lastPos = lastPos - el.childNodes[curNode].childNodes[0].textContent.length; 
     curNode++; 

     } 
     range.setStart(el.childNodes[curNode].childNodes[0], lastPos); 
     range.collapse(true); 
     sel.removeAllRanges(); 
     sel.addRange(range); 
    } 
    el.focus(); 
}; 


function savePos() { 
    lastPos = getCaretCharacterOffsetWithin(document.getElementById('editor')); 
} 

function addLink() { 
    console.log(lastPos); 

    setCaret(); 
    console.log(getCaretCharacterOffsetWithin(document.getElementById('editor'))); 

    console.log('focus'); 

    // $("#editor").focus(); 
    var link = $('#url').val(); 
    document.execCommand('createLink', false, link); 

} 

function getCaretCharacterOffsetWithin(element) { 
    var caretOffset = 0; 
    var doc = element.ownerDocument || element.document; 
    var win = doc.defaultView || doc.parentWindow; 
    var sel; 
    if (typeof win.getSelection != "undefined") { 
    sel = win.getSelection(); 
    if (sel.rangeCount > 0) { 
     var range = win.getSelection().getRangeAt(0); 
     var preCaretRange = range.cloneRange(); 
     preCaretRange.selectNodeContents(element); 
     preCaretRange.setEnd(range.endContainer, range.endOffset); 
     caretOffset = preCaretRange.toString().length; 
    } 
    } else if ((sel = doc.selection) && sel.type != "Control") { 
    var textRange = sel.createRange(); 
    var preCaretTextRange = doc.body.createTextRange(); 
    preCaretTextRange.moveToElementText(element); 
    preCaretTextRange.setEndPoint("EndToEnd", textRange); 
    caretOffset = preCaretTextRange.text.length; 
    } 
    return caretOffset; 
} 

fiddle

0

Dies ist, was Sie gefragt, In Ihrem Kopfgeld: Im folgenden Beispiel können Sie sehen, wie Sie die genaue Anzahl der Zeichen des aktuellen Punktes ermitteln können, an dem Sie mit der Maus geklickt haben o n:

<!-- Text Editor --> 
    <div id="editor" class="divClass" contenteditable="true">type here some text</div> 


    <script> 



    document.getElementById("editor").addEventListener("mouseup", function(key) { 

alert(getCaretCharacterOffsetWithin(document.getElementById("editor"))); 

}, false); 


function getCaretCharacterOffsetWithin(element) { 
var caretOffset = 0; 
var doc = element.ownerDocument || element.document; 
var win = doc.defaultView || doc.parentWindow; 
var sel; 
if (typeof win.getSelection != "undefined") { 
    sel = win.getSelection(); 
    if (sel.rangeCount > 0) { 
     var range = win.getSelection().getRangeAt(0); 
     var preCaretRange = range.cloneRange(); 
     preCaretRange.selectNodeContents(element); 
     preCaretRange.setEnd(range.endContainer, range.endOffset); 
     caretOffset = preCaretRange.toString().length; 
    } 
} else if ((sel = doc.selection) && sel.type != "Control") { 
    var textRange = sel.createRange(); 
    var preCaretTextRange = doc.body.createTextRange(); 
    preCaretTextRange.moveToElementText(element); 
    preCaretTextRange.setEndPoint("EndToEnd", textRange); 
    caretOffset = preCaretTextRange.text.length; 
} 
return caretOffset; 
} 
</script> 
Verwandte Themen