浏览器误读 Document.write()

Browser Misreading Document.write()

老实说,我不太确定这个问题的标题是否正确,因为我无法确定问题所在。另外,请记住,关于进化算法,我还有很多东西要学习,无论如何我都不是他们的大师。

下面的代码是一个简单的遗传算法的代码,如果您想这样称呼它的话。它缺少一个真实的、完整的遗传算法的多个特征,但它只是一个演示示例。它所做的只是获取一个字符串(在本例中由我预先确定)并对其进行变异,一次一个字符,直到字符串变为 "Hello, world!"。看看:

var source2 = "og834tnUEF*bt"; //random string
var target2 = "Hello, world!";

function fitness(source, target) {
    var fitval = 0;
    for(var i = 0; i < source.length; i++) {
        fitval += Math.pow(target.charCodeAt(i) - source.charCodeAt(i), 2);
    } return (fitval);
}

function mutate(source) {
    var charpos = Math.floor(Math.random() * source.length);
    parts = source.split("");
    var temp = String.fromCharCode(source.charCodeAt(charpos) + (Math.random() < 0.5 ? -1 : 1));
    parts[charpos] = temp;
    return (parts.join(""));
}

//functions end

var fitval = fitness(source2, target2);
var p = 0;
while(true) {
    p += 1;
    mutant = mutate(source2);
    mutFit = fitness(mutant, target2);
    if (mutFit < fitval) {
        fitval = mutFit;
        source2 = mutant;
        document.write(p + " : " + mutFit + "  :  " + mutant + "<br />");
    } if (fitval === 0) break;
}

我认为算法的描述不太重要,因为我对代码没有问题。这行在这里:

document.write(p + " : " + mutFit + "  :  " + mutant + "<br />");

似乎给我带来了问题。虽然最后包含一个换行符,但浏览器中的输出每隔一段时间就会无缘无故地分组。在此处查看 JSFiddle:https://jsfiddle.net/oaahzsuf/

注意到输出被捆绑了吗?我发现每次分号发生突变时似乎都会发生分组,但我不知道这与任何事情有什么关系。关于问题是什么的任何想法?我觉得我忽略了一些简单的事情,所以感谢您的帮助。

您的随机字符生成器正在输出 < 个字符!

也许让你的字符生成器只允许它创建有效的字符,这些字符实际上会出现在你的输出中。


如果你真的想要这些角色,那么escape the html entities像这样:

function htmlEscape(str) {
    return String(str)
            .replace(/&/g, '&amp;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;');
}

...

document.write(p + " : " + htmlEscape(mutFit) + "  :  " + htmlEscape(mutant) + "<br />");

此外,不要使用 document.write

如果执行页面 after the page has full loaded,则可以将输出附加到 <body> 元素。

document.addEventListener("DOMContentLoaded", function(event) { 
  var documentBody = document.getElementsByTagName('body')[0];
  //do work
  documentBody.innerHTML += p + " : " + mutFit + "  :  " + mutant + "<br />";
});

如果您 console.log 将每个字符串附加到输出 div,那么您会注意到其中一些字符串会破坏您的 <br> 标签,因为它们包含 HTML 个字符,例如 <innerHTML 尝试将字符串解析为 HTML(我检查了 jsFiddle,您在其中使用了 innerHTML)。 同样的问题发生在 document.write.

最简单的解决方案是在第二个连接操作上附加 <br> 标记。

像这样:

https://jsfiddle.net/oaahzsuf/1/

output.innerHTML += (p + " : " + mutFit + "  :  " + mutant);
output.innerHTML += '<br />';

如果您的字符串有可能包含完整标签 <>,那么您可以这样做:

output.innerText += (p + " : " + mutFit + "  :  " + mutant);
output.innerHTML += '<br />';

innerText威胁字符串为纯文本。

第三个选项是在字符串周围使用 <pre> 标记:

https://jsfiddle.net/oaahzsuf/4/

output.innerHTML += (p + " : " + mutFit + "  :  <pre>" + mutant + "</pre><br />");

第四个选项是像@Joe 指出的那样转义字符串。

此外,在循环中多次调用 document.getElementById 可能不是最好的事情。只需在循环外保存对 output div 的引用。