在过去的几周里,我一直在做一个复杂的项目,这时我遇到了这个奇怪的bug。我已经隔离了我的问题在下面的代码,这是最小的可能有效的HTML和JS,再现它:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Chat</title>
<script type="text/javascript">
//<![CDATA[
function refresh()
{
var old = document.getElementById("conversation").innerHTML;
var message = '<img/>';
if(old != message) {
alert("Old:n" + old);
alert("New:n" + message);
//alert("Refreshed!");
document.getElementById("conversation").innerHTML = message;
}
}
//]]>
</script>
</head>
<body onload="refresh()">
<div id="conversation"></div>
<script type="text/javascript">var myVar = setInterval(function(){refresh();},1000);</script>
</body>
</html>
函数refresh()
每秒钟检查一次div
中的代码是否与存储的字符串不同。如果不相同,则用该字符串替换div
的内容。然而,每次检查时,它看到的内容和存储的字符串是不同的。虽然字符串是<img/>
,但是innerHTML
返回为<img>
。我发现,对于任何自关闭标签,它会自动删除斜杠。对于不应该自关闭的标记(如<i>
),它会自动将其分成两个标记(如<i></i>
)。对于任何其他标签或文本,它不做任何事情。
我真的不明白为什么div
的内容在改变。如果有人能解释一下原因,我将不胜感激。如果有人能提供一个可能的解决方案,我将不胜感激。
这是因为浏览器对页面使用的是HTML解析器,而不是XML解析器,这就是它将删除结束斜杠的原因。
我自己也是一个新手但我认为Matt Ball指的是你在创建一个字符串的时候你应该创建一个新的DOM元素所以一个简单的改变你的函数将是:
var convo = document.getElementById("conversation");
function refresh() {
var old = convo.innerHTML;
var message = document.createElement("IMG");
if (old != message) {
alert("Old:n" + old);
alert("New:n" + message);
//alert("Refreshed!");
convo.innerHTML = message;
}
}
这是一个小提琴
注意:我添加了全局convo
变量以减少击键次数,并使用document.createElemet
而不是innerHTML
来向DOM添加新的图像元素。然后,您可以使用firstChild
方法在函数内部或外部调用该图像元素,如下所示:
convo.firstChild;