有没有简单的方法以任意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'是不可配置的。 –