有沒有簡單的方法以任意HTML字符串,要做到這一點,沒有。
問題是您使用的是任意的HTML字符串。目前在元素上設置任意HTML的唯一方法是使用innerHTML
。你必須找到一種不同的方式來設置一個元素上任意的HTML,例如追加HTML到一個臨時節點,抓住它的內容:
// Attempt: build a temporary element, append the HTML to it,
// then grab the contents
var div = document.createElement('div');
div.innerHTML = new_value;
var elements = div.childNodes;
for(var i = 0; i < elements.length; i++) {
this.appendChild(elements[ i ]);
}
然而,這遭受了同樣的問題,div.innerHTML = new_value;
將永遠因爲遞歸您正在修改任意HTML設置的唯一入口點。
我能想到的唯一解決方案是實現一個真實的,完整的HTML解析器,可以採取任意HTML字符串,並將其轉化爲DOM的東西像document.createElement('p')
等等,然後你可以添加到您當前的元素與appendChild
節點。然而,這將是一個可怕的,過度工程化的解決方案。
所有這一切,你不應該這樣做。這段代碼會毀了某人的一天。這違反了我們在前端開發中欣賞的幾個原則:
- 不要修改默認對象原型。任何碰巧運行此代碼,或者甚至在同一頁面上運行代碼(如第三方跟蹤庫)的人都會從他們的底下拉出地毯。追蹤發生什麼問題幾乎是不可能的 - 沒有人會想到尋找
innerHTML
劫持。
- 安裝人員通常用於計算屬性或具有副作用的屬性。你在劫持一個值並改變它。你面臨着一個消毒問題 - 如果有人第二次設置了已被劫持的價值,會發生什麼?
- 不要編寫棘手的代碼。這段代碼毫無疑問是一個「棘手」的解決方案。
最乾淨的解決方案可能只是在需要的地方使用my_function
。這是可讀的,短的,簡單的,香草編程:
someElement.innerHTML = my_function(value);
你可以或者定義的方法(因爲它則會覆蓋從用戶的價值,我會做了財產法),如:
Element.prototype.setUpdatedHTML = function(html) {
this.innerHTML = my_function(html);
}
這當開發人員遇到這種情況時,它顯然是非標準的,他們可以更輕鬆地尋找劫持Element原型的人。
沒有必要定義一個新的getter,你可以讓它使用舊的。 – Oriol
@Oriol True,編輯答案。謝謝你的提示。 – noppa
很好的答案!但是這種策略在Safari上不起作用,因爲實現'innerHTML'是不可配置的。 –