将此脚本插入HTML文档时,会导致奇怪的行为。插入<br>
标签后,显示的textarea元素会丢失其值(我已在Chrome 42中对其进行了测试):
var text = document.createElement("textarea");
document.body.appendChild(text);
text.value = "text";
alert("value presents");
document.body.innerHTML += "<br>"; //(*)
alert("value absents");
这是什么原因?
答案 0 :(得分:4)
innerHTML
属性是一把大锤。
通过调用document.body.innerHTML += '<br>'
,您已完成的操作将从<body>
移除每个元素,并将其替换为碰巧共享的全新元素相同的结构。
value
属性设置在原始<textarea>
上,但全新的属性从未设置过value
属性。
如果您要做的只是追加<br>
元素,请创建一个并通过DOM api追加它:
var br = document.createElement('br');
document.body.appendChild(br);
答案 1 :(得分:2)
当您使用+=
运算符时,您正在执行的操作如下:
document.body.innerHTML += "<br>";
与:
相同document.body.innerHTML = document.body.innerHTML + "<br>";
因此,您将获取正文中的所有元素并转换为HTML代码,添加更多HTML代码,然后再将其转换为元素。
获取元素的HTML代码后,您只能获得创建它的原始HTML代码,而不是当前值。文本区域内的文本将重置为创建时的文本,即在设置value
属性之前。
要添加元素,您应该创建它并附加它。这不会破坏已经存在的元素:
var br = document.createElement("br");
document.body.appendChild(br);
答案 2 :(得分:2)
改变这个:
document.body.innerHTML += "<br>";
到此:
document.body.appendChild(document.createElement("br"));
这将向DOM添加一个新元素,而不是用所有新元素替换DOM的全部内容。
执行此操作时:
document.body.innerHTML += "<br>";
它相当于:
var str = document.body.innerHTML;
str += "<br>";
document.body.innerHTML = str;
因此,您将整个DOM转换为HTML字符串,在字符串的末尾添加一个东西,然后用新的HTML替换整个DOM,这将创建所有新元素。
除了以这种方式执行它的低效率之外,它还用不同的DOM元素替换所有DOM元素,因此任何DOM引用或事件处理程序现在都被破坏,并且您对DOM元素所做的任何动态更改都没有反映在HTML将会丢失。
答案 3 :(得分:1)
所以为什么不这样做
document.body.appendChild(document.createElement("br"));
因此,每当您使用innerHTML设置无法控制的字符串时,仍然存在安全风险。例如:
var name = "<img src=x onerror=alert(1)>"; el.innerHTML = name; // shows the alert
因此,建议您在插入纯文本时不要使用innerHTML;相反,使用node.textContent。这并不是将传递的内容解释为HTML,而是将其作为原始文本插入。