2010-01-21 26 views
0

我的意思是,以下面的HTML代碼爲例,忽略空格。是否有一些代碼可以用來定位一個元素以及它的父對象和文本索引的偏移量?

<p> 
    paragraph-text 
    <span> 
    span text 
    <i>it</i> 
    </span> 
</p> 

我有pNode對象和「一個」在「跨度文本」內pNode.innerHTML作爲一個整體,也就是23這裏的索引,因爲pNode.innerHTML =「段落文本<跨度>跨度文本< i> it </i> </span>「,則應當計算開放範圍標籤。

是否有一些現有的庫可以像變換(pElement,23)一樣使用,以便我可以獲得「spanElement和2」的預期元素和偏移量?

非常感謝。 問候,

史蒂夫

回答

1

你可以通過獲取innerHTML,改變它的偏移你要找的字符可能做到這一點,然後再解析和版本比較所產生的文本節點,找到一個在結果變更了data

例如。

function findTextFromMarkupIndex(el1, ix) { 
    // make comparison element 
    var el2= document.createElement(el1.tagName); 
    // replace any other use of * in its HTML out of the way 
    var html= el1.innerHTML.split('*').join('x'); 
    // insert a * at the given index in HTML 
    el2.innerHTML= html.substring(0, ix)+'*'+html.substring(ix); 
    // search the resulting DOM for the * and return the matching descandent from the original 
    return findTextInComparison(el1, el2, '*'); 
} 

function findTextInComparison(el1, el2, text) { 
    for (var i= 0; i<el1.childNodes.length; i++) { 
     var child1= el1.childNodes[i]; 
     var child2= el2.childNodes[i]; 
     if (child2.nodeType===3) { // TEXT_NODE 
      var ix= child2.data.indexOf(text); 
      if (ix!==-1) 
       return [child1, ix]; 
     } else if (child2.nodeType===1) { // ELEMENT_NODE 
      var result= findTextInComparison(child1, child2, text); 
      if (result!==null) 
       return result; 
     } 
    } 
    return null; 
} 

未經測試,但應該對文本內容中的字符起作用。如果需要,可以擴展它以查看屬性值,但不能在標記內部執行索引點,如元素或實體/字符引用。爲了達到這個目的,你基本上需要編寫一個完整的HTML解析器。

這聽起來像一個不尋常的要求,究竟什麼是你想怎麼辦? innerHTML中的索引可能非常脆弱,因爲此屬性的標記輸出的確切格式完全沒有標準化。

+0

Bobince,這正是我正在尋找的。你的代碼完美無缺!非常感謝! – Steve 2010-01-22 03:34:42

1

你在說什麼聽起來像一個DOM Range,這是在除了IE所有的主流瀏覽器實現的。根據HTML中的字符偏移來指定位置並不是一個好主意,因爲innerHTML的實現差別很大。一個DOM範圍有一個開始和結束邊界,每個邊界由節點和該節點內的偏移量指定。在您的例子中,你可以創建一個代表的位置範圍:

var span = pNode.childNodes[1]; 
var spanText = span.firstChild; 
var range = document.createRange(); 

// Next line takes into account whitespace at the start of the text node 
range.setStart(spanText, 6); 

// For illustration, create a range that contains the letter "a" and selects it 
range.setEnd(spanText, 7); 
var sel = window.getSelection(); 
sel.removeAllRanges(); 
sel.addRange(range); 

一旦你有一個範圍,你可以使用它的各種事情,如插入節點,定義用戶選擇和應用格式到Range所封裝的內容。

IE定義完全不同的對象稱爲TextRange具有根本不同的基於文本的方法,但用於許多相同的目的。要獲得與前面示例相同的TextRange,可以使用以下示例:

var textRange = document.body.createTextRange(); 
textRange.moveToElementText(pNode); 
textRange.moveStart("character", 17); 
textRange.collapse(); 

// For illustration, create a range that contains the letter "a" and selects it 
textRange.moveEnd("character", 1); 
textRange.select(); 
+0

添,感謝您的反饋,可以理解的。 – Steve 2010-01-22 04:59:29

相關問題