您首先正在測試#text
節點以查看文本是否包含您試圖突出顯示的單詞,但隨後在父元素的.innerHTML
上執行替換。這有幾個問題。
- 無限替代:當您修改父元素的
.innerHTML
時,您將更改childNodes
數組。這樣做的方式是在包含要替換的文本的數組中添加一個節點。因此,當您繼續掃描childNodes
陣列時,您總是會找到一個包含要替換的文本的(新)節點。因此,您再次替換它,創建childNodes
陣列中具有較高索引的另一個節點。無限重複。
- 使用RegExp替換
.innerHTML
屬性中的文本。雖然您已經測試過以確保您想要替換的文本實際上包含在文本節點中,但這並不妨礙您的RegExp從也替換元素的實際HTML中的任何匹配詞語(例如,在src="yourWord"
,href="http://foo.com/yourWord/bar.html"
,或者,如果試圖以突出話像style
,color
,background
,span
,id
,height
,width
,button
,form
,input
等)。
- 您不檢查以確保您沒有更改
<script>
或<style>
標籤中的文字。
- 您正在檢查您是否僅在文本節點中進行了更改(即您檢查了
node.nodeType === 3
)。如果你不檢查這個你也必須因使用.innerHTML
改變HTML以下可能出現的問題:
- 你可能最終會改變屬性,或者實際的HTML標籤,這取決於你正在與
.replace()
變化。這可能會完全破壞頁面佈局和功能。
- 當您更改
.innerHTML
時,該頁面部分的DOM將被完全重新創建。這意味着元素,而新元素可能是具有相同屬性的相同類型,任何附加到舊元素的事件偵聽器都不會附加到新元素。這可能會嚴重破壞頁面的功能。
- 重複更改大部分DOM可能需要大量計算以重新呈現頁面。根據您的操作方式,您可能會遇到顯着的用戶感知性能問題。
因此,如果你要使用正規替換的文本,你只需要在#text
節點的內容進行操作,而不是父母節點的.innerHTML
。因爲你想創造更多的HTML元素(如新<span style="">
元素,與子#text
節點),也有一些併發症。
不能HTML文本分配到文本節點來創建新的HTML節點:
沒有辦法到新的HTML直接分配給文本節點,並把它評價爲HTML,創建新的節點。分配到文本節點的.innerHTML
屬性將創建對象這樣的屬性(就像它會在任何對象),但不會改變屏幕(即#text
節點的實際值)上顯示的文本。因此,它不會完成你想要做的事情:它不會創建父節點的任何新的HTML子節點。
這樣做對頁面的DOM影響最小(即最不可能破壞頁面上現有的JavaScript)的方法是創建一個<span>
以包含您正在創建的新文本節點該#text
節點,是不是在你的有色<span>
)與您所創建的潛在多個<span>
元素一起。這將導致用單個<span>
元素替換單個#text
節點。雖然這會創建更多的後代,但它將使父元素中的子元素數量保持不變。因此,任何依賴於此的JavaScript都不會受到影響。鑑於我們正在改變DOM,沒有辦法不可能破壞其他JavaScript,但這應該儘量減少這種可能性。
的你如何能做到這一些例子:見this answer(替換詞在按鈕的單詞列表)和this answer(地方的所有文字,其中由空格隔開成按鈕<p>
元素)執行正則表達式充分擴展替換爲新的HTML。見this answer它基本上做同樣的事情,但讓一個鏈接(它有不同的實現橫貫用TreeWalker DOM來找到#text
節點,而不是在其他兩個例子使用的NodeIterator的)。
這裏是代碼將執行你是在document.body
希望每個文本節點上的更換和創造有style
是在文本的一部分不同所需要的新的HTML:
有是其他方式來做到這一點。但是,它們將對該特定元素的子元素結構(例如父元素上的多個附加節點)產生更顯着的變化。這樣做有更高的潛力,可以打破依賴於當前頁面結構的頁面上的任何JavaScript。實際上,像這樣的任何改變都有可能打破目前的JavaScript。
對這個答案的代碼從代碼this other answer of mine
你記錄了'replacedText'具有的值嗎? –
@ScottMarcus當我記錄'replacedText'時,它顯示正確的值,例如' teste'。但是,如果我在'element.innerHTML'上使用它,它會崩潰我的選項卡。 – rafaelcpalmeida
您確定在控制檯中顯示「\」'轉義序列嗎?您是否嘗試將字符串修改爲:'' $ 1「'? –