浏览器误读Document.write()

时间:2015-04-30 05:32:15

标签: javascript algorithm google-chrome browser 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/

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

2 个答案:

答案 0 :(得分:1)

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

也许让你的角色生成器只允许它创建实际存在于你输出中的有效字符。

如果你真的想要这些角色,那么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 />";
});

答案 1 :(得分:1)

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

最简单的解决方案是在第二个concat操作上附加<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的引用。