JS: innerHTML会导致内容在不经意间发生改变



在过去的几周里,我一直在做一个复杂的项目,这时我遇到了这个奇怪的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;

最新更新