2013-02-08 93 views
0

我需要在contentEditable div中獲取光標位置。我從Get a range's start and end offset's relative to its parent containerhttps://stackoverflow.com/a/4770562/2008261獲得了一些有用的功能。如何獲得包含HTML的contentEditable中的光標位置?

但是,這些功能都沒有幫助,因爲我需要在HTML中的實際位置,這是我所需要的。

,如果我有:

<div id="diva" contenteditable="true">Insert <b>text here</b></div> 

,我把光標只是單詞「text」,因爲它與文本涉及返回7之前。但我需要它返回10,就好像它處理contentEditabe div的內部HTML。

這些都是我之前提到的功能:

function getCaretCharacterOffsetWithin(element) { 
var caretOffset = 0; 
if (typeof window.getSelection != "undefined") { 
    var range = window.getSelection().getRangeAt(0); 
    var preCaretRange = range.cloneRange(); 
    preCaretRange.selectNodeContents(element); 
    preCaretRange.setEnd(range.endContainer, range.endOffset); 
    caretOffset = preCaretRange.toString().length; 
} else if (typeof document.selection != "undefined" && document.selection.type != "Control") { 
    var textRange = document.selection.createRange(); 
    var preCaretTextRange = document.body.createTextRange(); 
    preCaretTextRange.moveToElementText(element); 
    preCaretTextRange.setEndPoint("EndToEnd", textRange); 
    caretOffset = preCaretTextRange.text.length; 
} 
return caretOffset; 
} 

和:

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

var charCount = 0; 
while (treeWalker.nextNode()) { 
    charCount += treeWalker.currentNode.length; 
} 
if (range.startContainer.nodeType == 3) { 
    charCount += range.startOffset; 
} 
return charCount; 
} 
+1

您是否嘗試過使用像[rangy](https://code.google.com/p/rangy/)這樣的跨瀏覽器庫? – 2013-02-08 20:32:17

+0

@VladMagdalin,rangy真棒。它比我所需要的要多 – 2013-02-08 23:44:08

回答

0

有過之前解決這個(我創建了一個基於網絡的文字處理軟件):唯一可行的解​​決辦法是遍歷DOM樹並計算innerHTML和outerHTML長度,然後使用該範圍內的偏移量(如果有的話)。

我也非常不鼓勵使用CONTENTEDITABLE實現的,你會花更多的時間試圖解決的是與他們錯了,並試圖比你的編碼你真正想要的功能,以覆蓋其行爲。

我的實現是採取了一系列偏移走上前,直到它擊中了指定的邊界父的功能。有些事情要記住,以前的兄弟姐妹很容易添加,但包裝父母對屬性等的處理很棘手。

我的計算是採取一個節點"<div id="" class="" foo="bar">sometext</div>"的整個長度,減去innerHTML的長度,減去tagname的長度,並subtract 3拿到<div id="" class="" foo="bar">

長度,但除非你控制的創建該HTML,您的計數可能仍然是錯誤的,因爲根據瀏覽器在測試長度時,連續多個空格將返回爲1個字符或多個字符。

+0

如果我不使用contentEditable實現,我應該使用什麼。我無法實現textarea來滿足我的需求。我同意你的看法,它有許多問題,並且非常混亂,因爲我編寫了非常多的代碼,但是另一個解決方案是什麼? – 2013-02-08 21:17:19

+0

爲什麼你不能實現一個textarea?隱藏的textarea比iframe或內容編輯器更有用。 – runspired 2013-02-08 21:40:53

+0

實際上我正在使用它們,textarea和contentEditable。 contentEditable是用戶與之交互的內容,而textarea是隱藏的。當用戶在contentEditable中寫入某些東西或樣式時,它會反映在隱藏的textarea中。所以textarea保留了html標記,然後jQuery代碼在兩者之間架起了一座橋樑。但是我不能單獨使用textarea,因爲它不支持以HTML格式顯示文本。我認爲你的文字處理器實現了相同的概念。不是嗎? – 2013-02-08 22:59:48

相關問題