javascript - 为什么如果语句在 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';
}
解决方案
2 种不同的解决方案(所有 JS 与主要是 CSS)
- 将核心功能保留在 JS 中
- 利用 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);
推荐阅读
- angular - Angular DI 注入令牌的类型与工厂的返回值类型不匹配,但服务接受
- makefile - GNU make 中 for 循环中的字符串替换
- reactjs - React Native 固定页脚不会停留在滚动上
- javafx - GLUON Mobile 找不到基本名称 com.gluonapplication.views.primary 的捆绑包
- java - Java迭代列表的嵌套映射
- typescript - TypeScript 编译器无法从联合类型化参数中消除过滤类型
- flutter - Flutter SliverList 和 CustomScrollView 错误:'owner.debugCurrentBuilderTarget == this':不正确
- javascript - 一种计算字母出现次数的有趣方法
- android - 使用分页库 2 实现 LoadMore 功能
- java - 使用 Class.getResource() 和 ClassLoader.getResource() 时