2010-04-01 94 views
1

我跟着這個片段http://bytes.com/topic/javascript/answers/504399-get-all-text-nodes防止textnode(JS-HTML)

var xPathResult = document.evaluate(
'.//text()[normalize-space(.) != ""]', 
document.body, null, 
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, 
null); for (var i = 0, l = xPathResult.snapshotLength; i < l; i++) { 
var textNode = xPathResult.snapshotItem(i); 
textNode.data = textNode.data.replace(/somePattern/g, 'replacement'); 
} 

我想替換例如像|12|與相應的表情一定的模式轉義特殊字符! 但是當我做textNode.data.replace("|12|",'<.img src="favicon.ico"/>');例如 文戲是..<.img src="favicon.ico"/>.. 爲我檢查HTML我發現<.img src="favicon.ico"/>成爲逃到&lt;img src="favicon.ico"/&gt; 是能夠防止這一點,讓圖像顯示?這裏&lt;.img src="favicon.ico"/&gt;添加了額外的點目的

回答

5

是的,data總是純文本。這意味着您不必擔心會漏掉字符,但這也意味着您不能將<img>等標記添加到其中。

天真的前進方向是替換包含元素的innerHTML而不是使用文本界面。但是這會很快給你帶來很大的問題,部分原因是因爲回寫到innerHTML意味着你正在銷燬並替換元素中的每個現有節點(如果事件處理程序或表單值被銷燬,伴隨着煩惱),但也因爲簡單的字符串和正則表達式處理無法正確處理HTML。例如,如果您在任何屬性值內都有字符串|12|,則替換會造成大混亂。

更好:使用splitText在模式匹配的邊緣砍文本節點爲比特,然後替換表示與之匹配的新的DOM元素中的文本:

var pattern= /\|12\|/; 
var node= /* Text node you want to replace strings in */; 

while (match= pattern.exec(node.data)) { 
    var img= document.createElement('img'); 
    img.src= 'favicon.ico'; 

    node= node.splitText(match.index); 
    node= node.splitText(match[0].length); 
    node.parentNode.replaceChild(img, node.previousSibling); 
}; 

(注意的XPath的方法讓所有文本節點不可用的IE)

+0

這絕對是更好的方法。不要被innerHTML引誘。 – 2010-04-01 15:28:29

+0

不要忘記創建一個循環,它將完成它們,而不僅僅是第一個。 – 2010-04-01 15:30:24

+0

是的,此循環替換單個文本節點中所有出現的字符串;您仍然需要使用XPath或手動樹行走/'getElementsByTagName('*')'children來遍歷所有Text節點。 – bobince 2010-04-01 15:39:00

0

textNode.data是CDATA元素中: 謝謝

注意。你需要的是替換textNode.innerHTML