文本区域的下一个兄弟有什么问题?

What is wrong with the next sibling of the textarea?

当此脚本插入 HTML 文档时,会导致奇怪的行为。显示的 textarea 元素在 <br> 标签插入后丢失了它的值(我在 Chrome 42 中测试过):

var text = document.createElement("textarea");
document.body.appendChild(text);
text.value = "text";
alert("value presents");
document.body.innerHTML += "<br>"; //(*)
alert("value absents");

这是什么原因?

innerHTML 属性 是一把大锤。

通过调用 document.body.innerHTML += '<br>',您所做的就是从 <body> 中删除 每个 元素,并用 全新的 恰好共享相同结构的元素。

value 属性 是在原来的 <textarea> 上设置的,但全新的 value 属性 没有设置。

如果您只想追加一个 <br> 元素,请创建一个并通过 DOM api:

追加它
var br = document.createElement('br');
document.body.appendChild(br);

当您像这样使用 += 运算符时,您在做什么:

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);

那你为什么不这样做呢

document.body.appendChild(document.createElement("br"));

so there is still a security risk whenever you use innerHTML to set strings over which you have no control. For example: var name = "<img src=x onerror=alert(1)>"; el.innerHTML = name; // shows the alert For that reason, it is recommended you not use innerHTML when inserting plain text; instead, use node.textContent. This doesn't interpret the passed content as HTML, but instead inserts it as raw text.

read for details here

改变这个:

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 字符串,在字符串末尾添加一个东西,然后用一个新的替换整个主体 DOM HTML 的一部分将创建所有新元素。

除了这样做效率低下之外,它还会用不同的 DOM 元素替换所有 DOM 元素,因此任何 DOM 引用或事件处理程序现在都已损坏,任何动态您对 DOM 元素所做的未反映在 HTML 中的更改将会丢失。