2016-11-22 15 views
6

Tôi có div contentedittable nàylàm thế nào để có được vị trí dấu nháy của một div contenteditable trong đó có hình ảnh

<div contenteditable="true" id="text">minubyv<img src="images/smiley/Emoji Smiley-01.png" class="emojiText" />iubyvt</div> 

Dưới đây là một mô tả hình ảnh của đầu ra mã enter image description here

vì vậy tôi muốn nhận được caret vị trí của div và giả định rằng con trỏ là sau ký tự cuối cùng. Và đây là mã của tôi để nhận được vị trí trên xe hơi

function getCaretPosition(editableDiv) { 
    var caretPos = 0, 
    sel, range; 
    if (window.getSelection) { 
    sel = window.getSelection(); 
    if (sel.rangeCount) { 
     range = sel.getRangeAt(0); 
     if (range.commonAncestorContainer.parentNode == editableDiv) { 
     caretPos = range.endOffset; 
     } 
    } 
    } else if (document.selection && document.selection.createRange) { 
    range = document.selection.createRange(); 
    if (range.parentElement() == editableDiv) { 
     var tempEl = document.createElement("span"); 
     editableDiv.insertBefore(tempEl, editableDiv.firstChild); 
     var tempRange = range.duplicate(); 
     tempRange.moveToElementText(tempEl); 
     tempRange.setEndPoint("EndToEnd", range); 
     caretPos = tempRange.text.length; 
    } 
    } 
    return caretPos; 
} 

var update = function() { 
    console.log(getCaretPosition(this)); 
}; 
$('#text').on("mousedown mouseup keydown keyup", update); 

Nhưng vấn đề là nó trả về 6 thay vì 14. Vị trí dấu mũ quay trở lại 0 sau hình ảnh. Xin vui lòng là có một cách tôi có thể có được vị trí caret là 14 trong trường hợp này.

EDIT

Tôi muốn cũng để chèn một số yếu tố bắt đầu từ vị trí dấu nháy. vì vậy đây là chức năng của tôi để làm điều đó

selectStart = 0; 
var update = function() { 
    selectStart = getCaretPosition(this); 
}; 
function insertEmoji(svg){ 
    input = $('div#text').html(); 
    beforeCursor = input.substring(0, selectStart); 
    afterCursor = input.substring(selectStart, input.length); 
    emoji = '<img src="images/smiley/'+svg+'.png" class="emojiText" />'; 
    $('div#text').html(beforeCursor+emoji+afterCursor); 
} 

Trả lời

6

Xem Tim Down's câu trả lời trên Get a range's start and end offset's relative to its parent container.

Cố gắng sử dụng chức năng ông có để có được chỉ số chọn lọc với các yếu tố lồng nhau như thế này:

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

 
var update = function() { 
 
    console.log(getCaretCharacterOffsetWithin(this)); 
 
}; 
 
$('#text').on("mousedown mouseup keydown keyup", update);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div contenteditable="true" id="text">minubyv<img src="https://themeforest.net/images/smileys/happy.png" class="emojiText" />iubyvt</div>

tôi đã viết chức năng riêng của tôi, dựa trên Tim Down, mà làm việc như bạn muốn nó. Tôi đã thay đổi treeWalker để lọc NodeFilter.ELEMENT_NODE được insted của NodeFilter.SHOW_TEXT và bây giờ các yếu tố <img/> cũng được xử lý bên trong vòng lặp của chúng tôi. Tôi bắt đầu bằng cách lưu trữ range.startOffset và sau đó recurse thông qua tất cả các nút chọn cây. Nếu nó tìm thấy một nút img, thì nó chỉ thêm 1 vào vị trí; nếu phần tử nút hiện tại khác với số range.startContainer của chúng tôi, thì nó sẽ thêm độ dài của nút đó. Vị trí được thay đổi bởi một biến khác nhau lastNodeLength được thêm vào charCount tại mỗi vòng lặp. Cuối cùng, nó thêm bất cứ điều gì còn lại trong lastNodeLength vào charCount khi nó tồn tại vòng lặp và chúng ta có vị trí dấu cuối cùng chính xác, bao gồm các phần tử hình ảnh.

mã làm việc cuối cùng(nó trả 14 ở cuối, chính xác như mong muốn và bạn muốn)

function getCharacterOffsetWithin_final(range, node) { 
 
    var treeWalker = document.createTreeWalker(
 
     node, 
 
     NodeFilter.ELEMENT_NODE, 
 
     function(node) { 
 
      var nodeRange = document.createRange(); 
 
      nodeRange.selectNodeContents(node); 
 
      return nodeRange.compareBoundaryPoints(Range.END_TO_END, range) < 1 ? 
 
       NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT; 
 
     }, 
 
     false 
 
    ); 
 

 
    var charCount = 0, lastNodeLength = 0; 
 

 
    if (range.startContainer.nodeType == 3) { 
 
     charCount += range.startOffset; 
 
    } 
 

 
    while (treeWalker.nextNode()) { 
 
     charCount += lastNodeLength; 
 
     lastNodeLength = 0; 
 
     
 
     if(range.startContainer != treeWalker.currentNode) { 
 
      if(treeWalker.currentNode instanceof Text) { 
 
       lastNodeLength += treeWalker.currentNode.length; 
 
      } else if(treeWalker.currentNode instanceof HTMLBRElement || 
 
         treeWalker.currentNode instanceof HTMLImageElement /* || 
 
         treeWalker.currentNode instanceof HTMLDivElement*/) 
 
      { 
 
       lastNodeLength++; 
 
      } 
 
     } 
 
    } 
 
    
 
    return charCount + lastNodeLength; 
 
} 
 

 
var update = function() { 
 
    var el = document.getElementById("text"); 
 
    var range = window.getSelection().getRangeAt(0); 
 
    console.log("Caret pos: " + getCharacterOffsetWithin_final(range, el)) 
 
}; 
 
$('#text').on("mouseup keyup", update);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div contenteditable="true" id="text">minubyv<img contenteditable="true" src="https://themeforest.net/images/smileys/happy.png" class="emojiText" />iubyvt</div>

+0

Mã của bạn là mát mẻ nhưng tôi cần phải phát hiện tất cả html nội dung của div không onle văn bản, bởi vì tôi sẽ chèn một số ký tự vào div tại vị trí caret. Nhìn vào câu hỏi của tôi chỉnh sửa. –

+0

@doggiebrezy Tôi đã làm cho nó hoạt động như bạn muốn. Xem câu trả lời cập nhật của tôi. Tôi đã thử nghiệm nó trên Chrome và Firefox mới nhất. Nó không hoạt động trên IE mặc dù. –

+0

cảm ơn bạn đã chỉnh sửa nhưng hãy giúp tôi với một điều cuối cùng. Bây giờ tôi muốn chèn một số văn bản hoặc hình ảnh ở vị trí dấu mũ và vì vậy tôi chia div.html nhưng vấn đề là giả sử vị trí dấu mũ là 11, văn bản được chèn không tính hình ảnh đó là một nhưng toàn bộ img.html ở đó bằng cách đặt sai điểm mà tại đó nó được chèn vào, xin bạn có thể giúp tôi đếm số chuỗi trong div.html bao gồm phần tử img –

Các vấn đề liên quan