2015-12-04 20 views
16

私はコンテンツ編集可能なdivを持っており、ユーザーがリンク、画像、またはYouTube動画などを挿入できるようにしたいと考えています。現時点ではこれは私が持っているものです。コンテンツ編集可能な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>

あなたが見ることができるように、ユーザーがリンクアドレスを入力するために別のテキストボックスに入力する必要があります。その結果、リンクがエディタに追加されると、リンクはポインタ/キャレットが置かれていた位置に追加されません。

私の質問は、ポインタ/キャレットの位置を取得して設定する方法です。私はthis for setting the pointerのような他の質問を見たことがありますが、Chrome、Safari、Firefox、IE9 +を含む現代のすべてのブラウザでサポートされているソリューションを希望します。

アイデア?ありがとう。

編集:

Iしかし位置を取得し、それだけで、それがオンになっているラインに応じた位置を取得し、それ以下のコードを発見しました。 (|はカーソルがどこにあるか)私はこれを持っている場合たとえば:

This is some text 
And som|e more text 

それから私は、値7、ない24

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

リンク先のソリューションには、すべてのブラウザで動作するソリューションがあり、受け入れられたものを超えて読むだけです。カーソル位置を取得するために、これを試してください:http://stackoverflow.com/questions/4767848/get-caret-cursor-position-in-contentedit-area-containing-html-content – SunKnight0

+0

@ SunKnight0私は次のコードを試してみました。あなたが提供した解決策は、常に0として返されます。 '' {{{{{{}}}}}}} .com/questions/4811822/get-a-ranges-start-and-end-offsets-parent-container-relative/4812022#4812022 –

+0

'getElementById( 'editor')'を使用してください。あなたはバニラのJavaScriptとJQueryを混在させています。 – SunKnight0

答えて

3

良いリッチテキストエディタが現在行うには難しいものの一つであり、(それ自体でかなりのコーナーケースの非友好的なAPI、膨大な数のプロジェクトです、ブラウザ間の相違点、リストの続き)。既存のソリューションを試してみることを強くお勧めします。

使用することができますいくつかのライブラリが含まれます:

+0

答えがありがとうございます。しかし、コードミラーのようなコードエディタではなく、単純なテキストエディタが必要です。 –

+1

QuillとWYSIHTMLを追加していただきありがとうございます。これらは、あなたが質問で概説したものにはるかに適しているようです。 – SpeedySan

6

オンサイト関連情報のトンがありますが返されます。これは私と私のクライアントのために働く。

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

私はそれを完成することができます少しの助けを借りて解決策、

を見つけることを試みてきました。 これは私がSO上で見つけた答えと私の特技の組み合わせです。

、そのトリッキーその汚い...しかし、あなたは、あなたがそれを使用することができなければなりませんが、それは内側リンクをサポートするために、仕事のビットを必要とする場合

(カーソルあれば、それはアンカー内部のアンカーを作成するアンカーの上にあります)

はここに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

これはあなたが尋ねたものです、あなたの賞金の中で:あなたがマウスをクリックした実際のポイントの文字の正確な数を検出する方法を次の例で見ることができます。 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> 
関連する問題