2015-12-17 11 views
6

私はcontenteditable属性を持つdivを持っています。ユーザは、カーソルがある場所に複数の選択メニューを入力して挿入することができる必要がある。私はカーソル位置を取得し、最初の選択メニューを挿入することができましたが、最初のテキストノードでのみ機能します。その後、私はそれをユーザーがタイプか、クリックするたびに更新カーソル位置の編集可能なdiv内に複数の要素を挿入

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

:私はカーソルの位置を取得する方法です

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

次に、selectを追加するボタンの処理方法を示します。テキストノードの後に​​要素を挿入する方法がわからないので、私はbrタグを挿入して後で削除します。よりクリーンな方法が必要です、そうですか?

$('#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(); 
}) 

私はこの問題は、私は、テキストを分割し、そこに選択を挿入することができるように部分文字列を使用しています、とすぐに別のselectタグがあるので、サブが過ぎて行くことができないということだと思います最初のテキストノード。だから、私は別のアプローチですべてをやり直すはずですが、私は完全に立ち往生しています。 https://jsfiddle.net/8a63sosr/

ありがとう:

はここjsfiddleです!

答えて

2

問題は、HTML要素の場合、jQueryの意味では、text()で、html()ではないということです。

私はそこにいくつかの範囲パラメータとのより良い解決策だが、ここで何かを推測:だから

//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/

、何それがないことpos値にhtmlタグの長さを加えています。

よろしくお願いいたします。Alexander

+0

よろしくお願いします。ありがとう!! – pincfloit

関連する問題