我正在研究骑士巡演问题的可视化。我制作的算法递归地工作。如果我启用JavaScript,则不会加载页面(至少在Chrome中)。 http://labs.pieterdedecker.be/knightstour/knightstour.htm
为什么页面不会加载?我怎样才能解决这个问题?我知道我的实现可能不是计算解决方案的最有效方法,但我还在学校,我没有时间和经验来提出更有效的算法。我只是这样做,因为问题的可视化非常吸引人。
答案 0 :(得分:1)
Web浏览器在执行内联脚本时暂停页面加载。你的脚本可能陷入无限循环。
您应该将代码包装在函数中,并在页面加载时调用该函数(onLoad事件)。
修改强>
OP已经做出了这一改变。
答案 1 :(得分:1)
如果您以递归方式执行此操作,则浏览器无需更新UI。一种实现递归的方法,让UI刷新可以使用setTimeout()
,并且有一个短暂的超时,让UI在JS空闲时做一些事情。
答案 2 :(得分:1)
这是第一件跳出来的东西:
setTimeout(knightsTour(newX, newY, board, visitedFields), 10);
你在这里立即调用方法knightsTour
,而不是在超时之后。 setTimeout
采用函数引用和延迟。您可以通过在匿名方法中包装实际调用来修复您的语句
// method to generate an function reference with properly scoped variables
var fnGenerator = function(newX, newY, board, visitedFields) {
var wrapperFn = function() {
knightsTour(newX, newY, board, visitedFields)
};
return wrapperFn;
}
// call the generator and return the wrapping function
var fnToCall = fnGenerator(newX, newY, board, visitedFields);
// Go from there
setTimeout(fnToCall, 10);
所以我们正在生成一个新函数,它将您的实际调用包装到knightsTour
并提供正确的参数。使用单独的函数是必要的,因为你试图在循环中调用所有这些,如果你没有这样做,每次调用knightsTour
都会使用相同的参数值(参见javascript闭包)。 / p>
在此之后你的电路板将加载,你的序列将开始。
答案 3 :(得分:0)
您的标题完全解释了问题。只要脚本正在运行,浏览器就不会发生任何其他事情。
要查看脚本的进度,必须将进程分成小部分,以便执行它的一部分,然后将控制权返回给浏览器足够长的时间,以便显示该部分的结果。 / p>
您可以使用window.timeOut
方法将控制权返回给浏览器,并让浏览器尽快继续使用您的代码。
示例:
function workPart1() {
// Do one part of the process here
// Then let the browser update, and make it start part 2 after that:
window.setTimeout(workPart2, 0);
}
答案 4 :(得分:0)
如果我理解你的问题,你想在网页上直观地显示骑士的动作。如果您一次执行整个算法,您将看到的只是代码完成执行后的最后一步。
您需要修改算法,以便维护指示算法当前状态的变量,并且每次调用函数时,它都会计算下一步。然后,您可以使用setTimeout
延迟一段时间,或让用户点击按钮前进到下一步。