2015-05-09 75 views
0

将此脚本插入HTML文档时,会导致奇怪的行为。所显示的textarea元素losts其价值<br>标签插入后(我已经在Chrome 42测试吧):textarea的下一个兄弟姐妹有什么问题?

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

,这是什么原因呢?

回答

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将会丢失。

+0

特别感谢您的解释关于破碎的DOM参考 – yakov

4

innerHTML属性是大锤。

通过调用document.body.innerHTML += '<br>'你做了什么从<body>删除元素,并与发生在共享相同的结构全新元素取代了它们。

value财产被设置在原来的<textarea>,但全新的从未有过它的value属性集。

如果你想要做的就是追加一个<br>元素,创造一个并通过DOM API,其追加:

var br = document.createElement('br'); 
document.body.appendChild(br); 
+0

@ Mike'Pomax'Kamermans,'foo + = bar'与'foo = foo + bar'相同。所以我不认为这是相关的。整个DOM字符串正在被替换,只是它发生了一些共享相似的值。 – zzzzBov

2

当您使用+=运营商这样的你在做什么:

document.body.innerHTML += "<br>"; 

是一样的:

document.body.innerHTML = document.body.innerHTML + "<br>"; 

所以你正在服用的人l正文中的元素并转换为HTML代码,附加更多HTML代码,然后再次将其转换为元素。

当您获取某个元素的HTML代码时,您只能获取其创建的原始HTML代码,而不是当前值。文本区域内的文本重置为创建时的内容,即在设置value属性之前。

要添加一个元素,你应该创建它并追加它。这不会破坏那些已经存在的元素:

var br = document.createElement("br"); 
document.body.appendChild(br); 
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,而是将其作为原始文本插入。

read for details here

+0

虽然重要的信息,这不是问题的答案。 – Guffa

+0

@Guffa我认为我们最终都有同样的建议..最初我以为OP对innerHTML属性并不了解太多,所以认为他应该详细检查它......任何方式都要感谢.. – whatever