2015-12-17 5 views
6

Ich habe ein div mit dem contenteditable Attribut. Der Benutzer muss mehrere Auswahlmenüs eingeben und einfügen können, in denen sich der Cursor befindet. Ich habe es geschafft, die Cursorposition zu bekommen und das erste Auswahlmenü einzufügen, aber es funktioniert nur auf dem ersten Textknoten.Fügen Sie mehrere Elemente in ein editierbares Div an der Cursorposition ein

Das ist, wie ich die Cursor-Position erhalten:

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; 
    } 

ich es dann die verschiedenen Benutzertypen oder Klicks jedes Mal aktualisieren.

function updatePos() { 
    var el = document.getElementById("msg"); 
    pos = getCaretCharacterOffsetWithin(el); 
} 
document.body.onkeyup = updatePos; 
document.body.onmouseup = updatePos; 

Dann ist hier, wie ich den Knopf bin Handhabung, die die Auswahlhinzufügt. Ich bin nicht sicher, wie man ein Element nach einem Textknoten einfügt, also füge ich ein br Tag ein und entferne es später. Es muss einen saubereren Weg geben, oder?

$('#btn').click(function(){ 
     var selectList = document.createElement('select'); 
     var msg = $('#msg'); 
     $(msg).html(function(){ 
       var first = $(msg).html().substring(0, pos); 
       var last = $(msg).html().substring(pos); 
       return first + '<br>' + last; 
     }); 

     $(msg).contents().filter('br').after(selectList); 

     $(msg).contents().filter('br').remove(); 

     $(msg).focus(); 
}) 

Ich denke, das Problem ist, dass ich Teilzeichenfolge bin mit dem Text zu teilen und dort die Auswahl einfügen kann, und sobald es eine anderen select-Tag ist, ist der Teil nicht in der Lage Vergangenheit der gehen erster Textknoten Vielleicht sollte ich das Ganze mit einer anderen Herangehensweise wiederholen, aber ich bin völlig festgefahren.

Hier ist der jsfiddle: https://jsfiddle.net/8a63sosr/

Dank!

Antwort

2

Das Problem ist, dass für HTML-Elemente, gut, in Bezug auf jQuery, text(), nicht html().

Ich denke, es gibt eine bessere Lösung mit einigen Bereichsparameter, aber hier ist etwas:

//fix caret pos 
    var temlOffset = pos; 
    $('#msg').html().split(/(<[^>]+>)/g).forEach(function(el){ 
     if(temlOffset > 0){ 
      if(el.length && el[0] === '<'){ 
       pos += el.length; 
      } else { 
       temlOffset -= el.length; 
      } 
     } 
    }); 

https://jsfiddle.net/Lemz17L8/

Also, was es tut, ist die HTML-Tag Länge zum pos Wert hinzufügen.

Mit freundlichen Grüßen, Alexander

+0

Oh, richtig! Vielen Dank!! – pincfloit

Verwandte Themen