浏览器误读 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, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/</g, '<')
.replace(/>/g, '>');
}
...
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 的引用。
老实说,我不太确定这个问题的标题是否正确,因为我无法确定问题所在。另外,请记住,关于进化算法,我还有很多东西要学习,无论如何我都不是他们的大师。
下面的代码是一个简单的遗传算法的代码,如果您想这样称呼它的话。它缺少一个真实的、完整的遗传算法的多个特征,但它只是一个演示示例。它所做的只是获取一个字符串(在本例中由我预先确定)并对其进行变异,一次一个字符,直到字符串变为 "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, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/</g, '<')
.replace(/>/g, '>');
}
...
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 的引用。