创建的演示是为了说明下面描述的逻辑的工作原理 -
- 我使用 JavaScript 创建了 4x4 图 block ,而不是硬编码到 html 中
- 代码通过
setInterval(colScan,1000)实现无限循环中一一高亮列
- 当用户在 html body 上按下鼠标时,它会更改所选列中的列扫描 --> 行扫描,这也是通过
setInterval(rowScan,1000)
实现
- 当用户再次点击 html 正文时,它会更改行扫描 --> 列扫描
问题:
- 无论如何,colScan 始终处于激活状态,您可以在控制台日志中看到该列始终在增加。
- 当用户第二次点击时,不会重置为列扫描。
- 我认为出现问题的部分代码
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);
}
}
移动 rowScan
和 colScan
中的 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/