2016-11-24 38 views
2

我的HTML:如何設置包含文本和元素節點的組合CONTENTEDITABLE DIV的插入位置

<div id="text" contenteditable="true">abcd<img src="icon.gif"/>efgh</div> 

caret = 5;所以我想設置插入符poisition圖像後立即爲圖像處理作爲1個字符。

所以我寫了thise代碼:

var node = document.querySelector("div"); 
node.focus(); 
var textNode = node.firstChild; 
var caret = 5; 
var range = document.createRange(); 
range.setStart(textNode, caret); 
range.setEnd(textNode, caret); 
var sel = window.getSelection(); 
sel.removeAllRanges(); 
sel.addRange(range); 

但我得到這個錯誤:

Uncaught DOMException: Failed to execute 'setStart' on 'Range': The offset 5 is larger than or equal to the node's length (4).

請建議我如何才能實現這一目標?在我希望的插入位置之前,我可能會有幾個圖像,每個圖像將被視爲1個字符。

回答

1

您的textNode有3個子女(1個文本,1個文本,1個文本),因此您不可只使用firstChild

您需要遍歷<div>childNodes和跟蹤字符數,其中childNodenodeType等於Node.TEXT_NODE(見MDN here)。在字符數小於caret的值的情況下,您可以從caret中扣除該字符並移至下一個文本節點。

根據您的條件是:

I desire and each image would be treated as 1 character

代碼將扣除1從caret其中nodeType == 1Node.ELEMENT_NODE

這裏是多個圖標的代碼示例:

var node = document.querySelector("div"); 
 
node.focus(); 
 
var caret = 24; 
 

 
var child; 
 
var childNodeIndex = 0; 
 
for(var i=0; i<node.childNodes.length; i++) { 
 
    child = node.childNodes[i]; 
 
    // Node.ELEMENT_NODE == 1 
 
    // Node.TEXT_NODE == 3 
 
    if(child.nodeType == Node.TEXT_NODE) { 
 
    // keep track of caret across text childNodes 
 
    if(child.length <= caret) { 
 
     caret -= child.length; 
 
    } else { 
 
     break; 
 
    } 
 
    } else if (child.nodeType == Node.ELEMENT_NODE) { 
 
    // condition that 'each image would be treated as 1 character' 
 
    if(caret > 0) { 
 
     caret -= 1; 
 
    } else { 
 
    \t break; 
 
    } 
 
    }; 
 
    childNodeIndex += 1; 
 
} 
 

 
var textNode = node.childNodes[childNodeIndex]; 
 

 
// your original code continues here... 
 
var range = document.createRange(); 
 
range.setStart(textNode, caret); 
 
range.setEnd(textNode, caret); 
 
var sel = window.getSelection(); 
 
sel.removeAllRanges(); 
 
sel.addRange(range);
<div id="text" contenteditable="true">a<img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/><img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/><img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/><img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/>b<img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/>cdefghijkl<img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/>mnopq<img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/>rst<img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/>uvw<img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/>xyz<img src="https://www.splitbrain.org/_static/ico/circular/ico/add.png"/></div>

相關問題