JavaScript 布尔运算无效,循环出错

JavaScript Boolean is not working and looping goes wrong

创建的演示是为了说明下面描述的逻辑的工作原理 -

  1. 我使用 JavaScript 创建了 4x4 的图块,而不是硬编码到 html
  2. 代码通过setInterval(colScan,1000)
  3. 在无限循环中逐一突出显示列
  4. 当用户在 html body 上按下鼠标时,它会更改 column scan --> row scan in the 选中的列这也是通过setInterval(rowScan,1000)
  5. 实现的
  6. 当用户再次点击 html 正文时,它会更改 行扫描 --> 列扫描

问题:

  1. 无论如何,colScan 始终处于激活状态,您可以在控制台日志中看到该列始终在增加。
  2. 当用户第二次点击时,它不会重置为列扫描。
  3. 我认为出现问题的部分代码

createtiles();
var k = 0,
    m = 0,
    selected_col = "",
    mousePressed = false,
    col_scan = true,
    row_scan = false;

scanSelector();

function scanSelector() {
    if (col_scan) {
        setInterval(colScan, 1000);
    } else if (row_scan) {
        setInterval(rowScan, 1000);
    }
}

document.body.onmousedown = function() {
    mousePressed = true;
}

function colScan() {
    if (k > 2) k = 0;
    else k++;
    console.log("col  " + k);
    var col = ".j_" + k;
    $(".tiles").removeClass('highlighter');
    $(col).addClass('highlighter');
    if (mousePressed) {
        mousePressed = false;
        col_scan = false;
        row_scan = true;
        selected_col = col;
        scanSelector();
    }
}

function rowScan() {
    if (m > 2) m = 0;
    else m++;
    console.log("row " + m);
    var row = selected_col + (".i_" + m);
    $(".tiles").removeClass('highlighter');
    $(row).addClass('highlighter');
    if (mousePressed) {
        mousePressed = false;
        col_scan = true;
        row_scan = false;
        selected_col = "";
        scanSelector();
    }
}

function createtiles() {
    for (var i = 0; i < 4; i++) {
        for (var j = 0; j < 4; j++) {
            var divTile = $('<div>', {
                class: 'tiles ' + ("j_" + j) + " " + ("i_" + i)
            });
            divTile.appendTo('.comtile');
        }
    }
}

演示 -> https://codepen.io/xblack/pen/BdGzYx

createtiles();
var k = 0,
  m = 0,
  selected_col = "",
  mousePressed = false,
  col_scan = true,
  row_scan = false;

scanSelector();

function scanSelector() {
  if (col_scan) {
    setInterval(colScan, 1000);
  } else if (row_scan) {
    setInterval(rowScan, 1000);
  }
}

document.body.onmousedown = function() {
  mousePressed = true;
}

function colScan() {
  if (k > 2) k = 0;
  else k++;
  console.log("col  " + k);
  var col = ".j_" + k;
  $(".tiles").removeClass('highlighter');
  $(col).addClass('highlighter');
  if (mousePressed) {
    mousePressed = false;
    col_scan = false;
    row_scan = true;
    selected_col = col;
    scanSelector();
  }
}

function rowScan() {
  if (m > 2) m = 0;
  else m++;
  console.log("row " + m);
  var row = selected_col + (".i_" + m);
  $(".tiles").removeClass('highlighter');
  $(row).addClass('highlighter');
  if (mousePressed) {
    mousePressed = false;
    col_scan = true;
    row_scan = false;
    selected_col = "";
    scanSelector();
  }
}

function createtiles() {
  for (var i = 0; i < 4; i++) {
    for (var j = 0; j < 4; j++) {
      var divTile = $('<div>', {
        class: 'tiles ' + ("j_" + j) + " " + ("i_" + i)
      });
      divTile.appendTo('.comtile');
    }
  }
}
html,
body {
  margin: 0px;
  padding: 0px;
  height: 100%;
  min-height: 100%;
  overflow: hidden;
  font-family: 'Roboto', sans-serif;
  background: white;
}

* {
  box-sizing: border-box!important;
}

.conatiner {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  grid-template-area: "menu" "comContent";
}

.menu {
  grid-area: menu;
  height: 5vh;
  padding: 2vh;
}

.comtile {
  grid-area: comContent;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto;
  grid-gap: 0.5vh;
  height: 95vh;
  padding: 2vh;
}

.tiles {
  background: #F7F7F7;
  border-radius: 0.4vh;
  border: 1px solid #EEEBEB;
}

.highlighter {
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.15);
  transition: box-shadow 0.3s cubic-bezier(0.38, -0.76, 0, 1.69);
  border: 1px solid silver;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="container">
  <div class="menu">MAIN MENU</div>
  <div class="comtile"></div>
</div>

您需要进行以下更改:

出于@ASDFGerte 所述的原因,将 setInterval 替换为 setTimeout

function scanSelector() {
    if (col_scan) {
        // Replace setInterval with setTimeout
        setTimeout(colScan, 1000);
    } else i f (row_scan) {
        // Replace setInterval with setTimeout
        setTimeout(rowScan, 1000);
    }
}

移动 rowScancolScan 中的 scanSelector() 行。两种方法的变化是相同的,我将只显示 rowScan.

中的变化
function rowScan() {
    if (m > 2) m = 0;
    else m++;
    console.log("row " + m);
    var row = selected_col + (".i_" + m);
    $(".tiles").removeClass('highlighter');
    $(row).addClass('highlighter');
    if (mousePressed) {
        mousePressed = false;
        col_scan = true;
        row_scan = false;
        selected_col = "";
        // Remove this line
        // scanSelector();
    }
    // Because you're no longer using setInterval you need to call 
    // this method after each timeout.
    scanSelector();
}

每次调用 scanSelector() 都会创建另一个间隔。初始间隔将突出显示列,在第一次单击后,您有两个间隔 运行 并排:原始间隔和突出显示行的间隔。每次点击后,您只会添加间隔。

您可以存储间隔 ID,setInterval 的结果,并在从列更改为行突出显示时清除此间隔,反之亦然。更简单的解决方案是从 setInterval 移动到 setTimeout,如我在上面向您展示的更改中所述。