Javascript JS tic tac toe游戏中的讨厌虫

Javascript JS tic tac toe游戏中的讨厌虫,javascript,html,css,Javascript,Html,Css,const winCombos=[ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [6, 4, 2] ]; 让playerTurn='X'; for(设i=0;i

const winCombos=[
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[6, 4, 2]
];
让playerTurn='X';
for(设i=0;i<9;i++){
常量单元格=document.getElementById('c'+i);
cell.addEventListener('click',startName);
函数startName(){
cell.innerHTML=playerTurn;
if(checkForWin()){
警报(“游戏结束”);
}
}
}
函数checkForWin(){
for(设i=0;i
td{
边框:2倍实心#333;
高度:100px;
宽度:100px;
文本对齐:居中;
垂直对齐:中间对齐;
字体系列:“漫画无MS”,草书,无衬线;
字体大小:70px;
光标:指针;
}
桌子{
边界塌陷:塌陷;
位置:绝对位置;
左:50%;
左边距:-155px;
顶部:220px;
}
表tr:第一胎td{
边界顶部:0;
}
表tr:最后一个孩子td{
边界底部:0;
}
表tr td:第一个孩子{
左边框:0;
}
表tr td:最后一个孩子{
右边界:0;
}
.终局{
显示:无;
宽度:200px;
顶部:120px;
背景色:红色;
位置:绝对位置;
左:50%;
左边距:-100px;
填充顶部:50px;
填充底部:50px;
文本对齐:居中;
边界半径:5px;
颜色:白色;
字号:2em;
}

井字游戏
我看不见这篇文章

单击发生后,
startGame
侦听器立即同步运行,
alert
阻止浏览器-它阻止进一步的Javascript和重新呈现,直到警报解除。当函数运行时,浏览器还没有时间重新绘制

您可以使用
requestAnimationFrame
确保只有在浏览器完成重新渲染以显示新的
x
后,才会显示
警报:

  window.requestAnimationFrame(() => {
    setTimeout(() => {
      alert('game over');
    });
  });
const winCombos=[
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[6, 4, 2]
];
让playerTurn='X';
for(设i=0;i<9;i++){
常量单元格=document.getElementById('c'+i);
cell.addEventListener('click',startName);
函数startName(){
cell.innerHTML=playerTurn;
if(checkForWin()){
window.requestAnimationFrame(()=>{
设置超时(()=>{
警报(“游戏结束”);
});
});
}
}
}
函数checkForWin(){
for(设i=0;i
td{
边框:2倍实心#333;
高度:100px;
宽度:100px;
文本对齐:居中;
垂直对齐:中间对齐;
字体系列:“漫画无MS”,草书,无衬线;
字体大小:70px;
光标:指针;
}
桌子{
边界塌陷:塌陷;
位置:绝对位置;
左:50%;
左边距:-155px;
顶部:220px;
}
表tr:第一胎td{
边界顶部:0;
}
表tr:最后一个孩子td{
边界底部:0;
}
表tr td:第一个孩子{
左边框:0;
}
表tr td:最后一个孩子{
右边界:0;
}
.终局{
显示:无;
宽度:200px;
顶部:120px;
背景色:红色;
位置:绝对位置;
左:50%;
左边距:-100px;
填充顶部:50px;
填充底部:50px;
文本对齐:居中;
边界半径:5px;
颜色:白色;
字号:2em;
}

井字游戏
我看不见这篇文章

这里需要了解的重要一点是javascript在单线程模型中运行。现在让我们看一下你的代码:

cell.addEventListener('click', startGame);
function startGame() {
     cell.innerHTML = playerTurn;
     if(checkForWin()) {
          alert('game over');
     }
}
在click事件处理程序中,可以执行以下操作:

  • 更新单元格的内容
  • 检查是否有获胜的动作
  • 如果最后一步是成功的,则显示警报
  • 从CPU的角度来看,所有这些“操作”都是串行完成的,所以您希望首先呈现单元格的内容,对吗?然而,情况并非如此。当您设置单元格的innerHTML时,DOM将变脏,更改将在下一个渲染线程周期中呈现,该周期将在javascript线程空闲时发生。然而,您仍然有操作2和3挂起,因此它们首先被执行,然后当javascript线程变为空闲时,您的渲染线程将坐在前排并更新屏幕

    我希望现在您对javascript的工作原理有了清晰的认识

    现在,为了解决您的问题,您可以在显示警报之前设置一个较小的超时,以便在显示警报之前更新页面