试图在一个递归函数中一步步打印出来,而不是用Javascript一次性打印出来。

问题描述 投票:0回答:1

我想做一个N-Queens可视化器,我把我的求解器挂到了html文档上。我的问题是,我想一步一步地显示所有的东西,每一步的间隔是1秒,用于显示 场所 函数,而不是马上显示完成的解决方案。

换句话说,我想一步一步的显示每一步完成的动作。

我的放置函数,也是和DOM上的表格挂钩的,所以当它被放置在棋盘上的时候,它也会把它放置在html表格上。

function place(board, row, col, val, table) {
  const newRow = board[row].split('');
  newRow[col] = val;
  board[row] = newRow.join('');
  //place on DOM as well
  table.childNodes[row].childNodes[col].innerHTML = val;
}

而我的解算器的代码是这样的。

function solver(board, row, col, solutions) {
  if (col === board.length) {
    solutions.push([...board]);
    return;
  }

  const currentTable = listOfTables[solutions.length];

  for (let i = 0; i < board.length; i++) {
    if (canPlace(board, i, col)) {
      place(board, i, col, 'Q', currentTable);
      solver(board, row, col + 1, solutions);
      place(board, i, col, '.', currentTable);
    }
  }
}

我试图在求解器函数里面封装一个setTimeout,但是当超时的时候,还是会一次性运行所有的代码。

currentTable变量是用来知道DOM中的哪个表目前正在使用。

以下是包含所有代码的CodePen,如果有人需要的话。https:/codepen.iovvuspenKKVKMrq?editors=1111。

javascript html recursion dom timeout
1个回答
0
投票

你可以根据自己的喜好调整下面的代码。

您添加 display="none" 到你的所有表,然后你可以使用这个代码在一个时间间隔内停用属性

var i=0

setInterval(() => {
          for(z=i;z<listOfTables.length;z++)  {      
    const x=document.getElementsByClassName('new-table')[z]
          if (x.style.display === "none") {
              x.style.display = "";
                       i++                                
          }    
               break  
                       }
            }, 3000);

所以你的最终代码可能是这样的

const button = document.getElementById("button-click");
    const selection = document.getElementById("selection");
    let tablesContainer = document.getElementById("tables-container");
    let listOfTables = tablesContainer.childNodes;

    button.addEventListener("click", () => {
      console.log(nQueens(Number(selection.value)));

      listOfTables = tablesContainer.childNodes;
     // add this code to your eventlistner or anywhre you want to show something in time interval
      var i=0
       setInterval(() => {

          for(z=i;z<listOfTables.length;z++)  {      
    const x=document.getElementsByClassName('new-table')[z]

          console.log(z)
          if (x.style.display === "none") {
              x.style.display = "";
                       i++                                
          }    
               break  
                       }
            }, 3000);

    });

    selection.addEventListener("change", (e) => {
      let numOfTables = e.target.value;

      if (numOfTables === 1) numOfTables = 1;
      else if (numOfTables === 4) numOfTables = 3;
      else if (numOfTables === 8) numOfTables = 93;

      const rowsCols = e.target.value;
      for (let allTables = 1; allTables < numOfTables; allTables++) {
        const newTable = document.createElement("table");
        newTable.classList = "new-table";
        newTable.style.display="none"// add this attribute to all your tables
        for (let i = 0; i < rowsCols; i++) {
          const row = document.createElement("tr");

          for (let j = 0; j < rowsCols; j++) {
            const th = document.createElement("th");
            th.innerHTML = ".";
            row.appendChild(th);
          }
          newTable.appendChild(row);
        }
        tablesContainer.appendChild(newTable);
      }
    });
© www.soinside.com 2019 - 2024. All rights reserved.