首页 > 解决方案 > 为什么如果语句在 JavaScript 中重复时不起作用?

问题描述

我正在尝试制作一个网格,其中不同的框将根据我的 HTML 文档中定义的二进制值闪烁。我在 HTML 中创建了一个网格,其中背景颜色自动为绿色,我想要实现的是,如果每个网格项的值从 0 变为 1,它会将颜色变为红色并闪烁分别。

我设法让第一个工作,并认为我可以重复分配不同变量的代码,但这没有奏效。奇怪的是,如果我删除第一个框的代码,第二个框将开始工作。

我是否需要在 JS 中添加一些额外的代码来分隔 if 语句?

CSS'

.grid-container {
  display: grid;
  grid-gap: 50px;
  grid-template-columns: auto auto auto;
  background-color: grey;
  padding: 10px;
}

.grid-item {
  background-color: green;
  border: 1px solid rgba(0, 0, 0, 0.8);
  padding: 50px;
  font-size: 30px;
  text-align: center;
}

HTML

<div class="grid-container">
  <div class="grid-item" id = "blink1">A</div>
  <div class="grid-item" id = "blink2">B</div>
 
</div>


<div class = "values">  
<div id = "$box1value"> 1 </div>
<div id = "$box2value"> 1 </div>
</div>

JS

var $box1 = document.getElementById("$box1value").innerHTML;

if ($box1 > 0) {
    document.getElementById("blink1").style.backgroundColor = '#ff0000';
    // blink "on" state
    function show() {
        if (document.getElementById)
            document.getElementById("blink1").style.visibility = "visible";
    }
    // blink "off" state
    function hide() {
        if (document.getElementById)
            document.getElementById("blink1").style.visibility = "hidden";
    }

    for (var i = 900; i < 99999999999; i = i + 900) {
        setTimeout("hide()", i);
        setTimeout("show()", i + 450);
    }

} else {
    document.getElementById("blink1").style.backgroundColor = '#098700';
}




/////////////////////next box/////////////////////////////

var $box2 = document.getElementById("$box2value").innerHTML;

if ($box2 > 0) {
    document.getElementById("blink2").style.backgroundColor = '#ff0000';// blink "on" state
    function show() {
        if (document.getElementById)
            document.getElementById("blink2").style.visibility = "visible";
    }
    // blink "off" state
    function hide() {
        if (document.getElementById)
            document.getElementById("blink2").style.visibility = "hidden";
    }

    for (var i = 900; i < 99999999999999999; i = i + 900) {
        setTimeout("hide()", i);
        setTimeout("show()", i + 450);
    }

} else {
    document.getElementById("blink2").style.backgroundColor = '#098700';
}

标签: javascripthtml

解决方案


2 种不同的解决方案(所有 JS 与主要是 CSS)

  1. 将核心功能保留在 JS 中
  2. 利用 CSS 实现核心功能

我看到你在这里想要实现的目标,并且我看到了几种不同的方法来实现这一目标。以下两种解决方案都允许您的代码动态循环任意数量的盒子项目——无需为每个项目编写单独的块。

下面的第一个示例的建模与您的更相似,基于您的代码,但经过重写以更动态地工作。第二种解决方案通过将所有初始化脚本移动到 CSS 中大大简化了事情,如果您需要进行任何实时状态切换,则让 JS 只负责布尔切换。


#1。将核心功能保留在 JS 中

此解决方案修改您的原始代码以动态读取有多少值的值,然后循环它们。为了在 JS 中执行重复闪烁,我建议使用 setInterval。使用循环时,您还需要将其移到其余代码之外,否则最终会导致循环的迭代器与 setInterval 和 setTimeout 的计时发生冲突。更多关于这里。您可以在下面看到工作示例:

function blink(el) {
    if (el.style) {
        setInterval(function() {
            el.style.visibility = "visible";
            setTimeout(function() {
                el.style.visibility = "hidden";
            }, 450);
        }, 900);
    }
}

const $boxes = document.querySelectorAll('[id^="blink"]');
for (const $box of $boxes) {
    var boxId = $box.id.match(/\d+/)[0]; // store the ID #
    if (document.getElementById('$box' + boxId + 'value')) {
        var boxValue = parseInt(document.getElementById('$box' + boxId + 'value').innerHTML);
        if (boxValue) {
            $box.style.backgroundColor = '#ff0000';
            blink($box);
        } else {
            $box.style.backgroundColor = '#098700';
        }
    }
}
.grid-container {
    display: grid;
    grid-gap: 50px;
    grid-template-columns: auto auto auto;
    background-color: grey;
    padding: 10px;
}
.grid-item {
    background-color: #098700;
    border: 1px solid rgba(0, 0, 0, 0.8);
    padding: 50px;
    font-size: 30px;
    text-align: center;
}
.values {
    display: none;
}
<div class="grid-container">
    <div class="grid-item" id="blink1">A</div>
    <div class="grid-item" id="blink2">B</div>
    <div class="grid-item" id="blink3">C</div>
</div>
<div class="values">  
    <div id="$box1value">1</div>
    <div id="$box2value">0</div>
    <div id="$box3value">1</div>
</div>

代码笔: https ://codepen.io/brandonmcconnell/pen/ecc954bad5552962574c080631700932


#2。利用 CSS 实现核心功能

此解决方案将所有 JS 代码(颜色和动画)移动到 CSS,将二进制布尔开关 0/1 移动到网格项目本身的数据属性而不是单独的项目,然后使用 JS 触发这些容器上的任何布尔开关通过使用另一个属性(例如 ID)来定位它们,或者正如我在下面的示例中使用的那样,我调用的另一个数据属性data-blink-id. 如果您能够将所有这些逻辑移动到 CSS 中,这是我推荐的解决方案。实时维护和操作会容易得多,因为更改状态所需的只是一个简单的布尔开关。

.grid-container {
    display: grid;
    grid-gap: 50px;
    grid-template-columns: auto auto auto;
    background-color: grey;
    padding: 10px;
}
.grid-item {
    background-color: #098700;
    border: 1px solid rgba(0, 0, 0, 0.8);
    padding: 50px;
    font-size: 30px;
    text-align: center;
}
.grid-item[data-blink-status="1"] {
    background-color: #f00;
    animation: blink 900ms linear infinite forwards;
}
@keyframes blink {
    0%, 50% { opacity: 1; }
    51%, 100% { opacity: 0; }
}
<div class="grid-container">
    <div class="grid-item" data-blink-id="1" data-blink-status="1">A</div>
    <div class="grid-item" data-blink-id="2" data-blink-status="0">B</div>
    <div class="grid-item" data-blink-id="3" data-blink-status="1">C</div>
</div>

代码笔: https ://codepen.io/brandonmcconnell/pen/5b4f3090b3590902b11d50af43361758

要触发项目上的二进制布尔开关(打开/关闭),请使用以下 JS 命令。我已经在上面链接的 CodePen 示例中对此进行了注释。取消注释此 JS 行以激活它并使用data-blink-id=2

document.querySelector('[data-blink-id="2"]').setAttribute('data-blink-status', 1);

推荐阅读