2015-12-04 15 views
16

Tôi có một div có thể chỉnh sửa được mà tôi muốn có thể đưa người dùng chèn những thứ như liên kết, hình ảnh hoặc video trên YouTube. Tại thời điểm này đây là những gì tôi có:Nhận và đặt vị trí con trỏ với div có thể chỉnh sửa nội dung

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>

Như bạn có thể thấy, người dùng phải gõ vào một hộp văn bản riêng biệt để nhập địa chỉ liên kết. Do đó, khi liên kết được thêm vào trình chỉnh sửa, nó sẽ không được thêm vào vị trí mà con trỏ/dấu nháy đã được bật.

Câu hỏi của tôi là cách tôi có thể nhận và đặt vị trí của con trỏ/dấu mũ. Tôi đã thấy các câu hỏi khác như this for setting the pointer tuy nhiên tôi muốn có một giải pháp được hỗ trợ trong tất cả các trình duyệt hiện đại, bao gồm Chrome, Safari, Firefox và IE9 +.

Bất kỳ ý tưởng nào? Cảm ơn.

Edit:

tôi thấy đoạn code dưới đây mà được vị trí tuy nhiên, nó chỉ được vị trí theo dòng đó là ngày. Ví dụ nếu tôi có điều này (nơi | là con trỏ):

This is some text 
And som|e more text 

Sau đó, tôi sẽ được trả lại giá trị 7, không 24.

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

Giải pháp bạn liên kết không có giải pháp hoạt động trên tất cả các trình duyệt, chỉ cần đọc vượt quá giải pháp được chấp nhận. Để nhận vị trí con trỏ, hãy thử cách này: http://stackoverflow.com/questions/4767848/get-caret-cursor-position-in-contenteditable-area-containing-html-content – SunKnight0

+0

@ SunKnight0 Tôi đã thử đoạn mã sau từ giải pháp bạn cung cấp tuy nhiên nó trả về như mọi khi 0.'var editor = document.getElementById ('# editor'); ' ' console.log (getCaretCharacterOffsetWithin (editor)); 'Tôi đã sử dụng hàm từ câu trả lời http: // stackoverflow này .com/questions/4811822/get-a-range-start-and-end-offsets-relative-to-its-parent-container/4812022 # 4812022 –

+0

Sử dụng 'getElementById ('editor')'. Bạn đang trộn vani JavaScript với JQuery. – SunKnight0

Trả lời

3

một biên tập viên giàu văn tốt là một trong những điều khó khăn hơn hiện nay để làm, và có khá nhiều dự án bằng cách riêng của mình (không thân thiện API, số lượng lớn các trường hợp góc , sự khác biệt giữa các trình duyệt, danh sách tiếp tục). Tôi mạnh mẽ khuyên bạn nên thử và tìm một giải pháp hiện có.

Một số thư viện có thể được sử dụng bao gồm:

+0

Cảm ơn câu trả lời của bạn tuy nhiên tôi muốn một trình soạn thảo văn bản đơn giản hơn là một trình soạn thảo mã như gương mã. –

+1

Cảm ơn bạn đã thêm Quill và WYSIHTML. Đây dường như là một phù hợp hơn cho những gì bạn vạch ra trong câu hỏi. – SpeedySan

6

Có một tấn thông tin liên quan tại chỗ. Điều này làm việc cho tôi và khách hàng của tôi.

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

Tôi đã cố gắng để tìm một giải pháp,

Với một chút giúp đỡ nó có thể được hoàn thiện. Đó là sự kết hợp các câu trả lời tôi đã tìm thấy trên SO và điểm kinh nghiệm của tôi.

phức tạp của nó, lộn xộn của nó ... nhưng nếu bạn phải, bạn có thể sử dụng nó nhưng nó đòi hỏi một chút công việc để hỗ trợ các liên kết bên trong (nếu bạn trỏ là trên một neo nó sẽ tạo ra neo bên neo)

đây là 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

Đây là những gì bạn yêu cầu, trong tiền thưởng của bạn: trên ví dụ sau, bạn có thể xem cách phát hiện chính xác số ký tự của điểm thực tế nơi bạn đã nhấp chuột 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> 
Các vấn đề liên quan