JavaScript boolean 运算不工作且循环出错

标签 javascript boolean setinterval infinite-loop

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

  1. 我使用 JavaScript 创建了 4x4 图 block ,而不是硬编码到 html 中
  2. 代码通过setInterval(colScan,1000)实现无限循环中一一高亮列
  3. 当用户在 html body 上按下鼠标时,它会更改所选列中的列扫描 --> 行扫描,这也是通过setInterval(rowScan,1000)
  4. 实现
  5. 当用户再次点击 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,如我上面向您展示的更改中所述。

关于JavaScript boolean 运算不工作且循环出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45941972/

相关文章:

javascript - 使用 JQuery/CSS 在页面上滑动 Div

javascript - Django 使用plotly 和表单中的数据绘制图表

symfony - 如何在 Twig 中显示 boolean 值

javascript - 第一次立即执行 setInterval 函数

javascript - iPhone 上滚动事件内的 SetInterval - 为什么此代码不起作用?

Javascript onDrop 属性未分配

javascript - 想要在文本中插入选定的值

c# - C#中三元运算符报错: Only assignment, call, increment, decrement, new object expressions可以作为语句使用

MYSQL boolean 类型

javascript - js中其他方法调用setInterval方法无法访问对象属性