if语句中的javascript迭代
javascript iteration within if statement
在这个JSFiddle中(问题代码注释掉),第一次点击空单元格将在隐藏输入中设置一个值,并将单元格的bgcolor设置为绿色。点击第二个空表格单元格,设置另一个隐藏输入的值,并将第二个单元格bgcolor更改为红色。
现在,根据另一个SO问题的反馈,我试图通过循环表中所有td的数组(所有注释掉的代码)来实现一个检查,看看onclick,任何单元格是否已经分别将bgcolor设置为绿色/红色,如果为true,则将bgcolor设置为空/空白,以允许NEW单元格选择获得bgcolor,所以应该总是只有一个绿色块和一个红色块。有人能向我解释一下我是如何实现循环并检查错误而没有得到预期结果的吗。
数组循环在这里起作用——当不是现有代码的一部分时,使用jsfiddle。但当我把它添加到需要的代码中时,它就不起作用了。
HTLM
<div id="starget"></div>
<div id="etarget"></div>
<table width="100%" id="test">
<thead>
<tr>
<th>Tech</th>
<th>0800</th>
<th>0900</th>
<th>1000</th>
<th>1100</th>
<th>1200</th>
</tr>
</thead>
<tr>
<td>Bill</td>
<td>XXX</td>
<td onclick="res(0900,this);"></td>
<td>XXX</td>
<td>XXX</td>
<td onclick="res(1200,this);"></td>
</tr>
</table>
脚本
var x = 0;
var click = 0;
/* tdElements = document.getElementsByTagName("td"); */
/* I have tried the tdelements array inside and outside of the function */
function res(zz,el) {
if (click == 0) {
/* for(var key in tdElements) {
if (tdElements[key].style.backgroundColor=="green") {
tdElements[key].style.backgroundColor="";
}
} */
document.getElementById('starget').innerHTML=zz;
click = 1;
el.style.backgroundColor='green';
}
else {
/* for(var key in tdElements) {
if (tdElements[key].style.backgroundColor=="red") {
tdElements[key].style.backgroundColor="";
}
} */
document.getElementById('etarget').innerHTML=zz;
click = 0;
el.style.backgroundColor='red';
}
}
如果调用.getElementsByTagName
,则不会返回array
!您将返回一个liveHTMLCollection
元素,其中包含一些在使用for.. in
循环时无法忽略的其他项目。for
循环将派上用场,因为您的实时HTMLCollection
包含您可以使用的length
!
/* HTMLCollections come with a length attribute we can use
* as every item is numbered, but in a object-style key-value pair */
for(var i = 0; i < tdElements.length; i++){
/* This was tripping up your code - the `item` function to fetch an
* element at the index defined in the HTMLCollection*/
tdElements.item(i).style.backgroundColor = "green"
}
这将使所有背景变为绿色。现在你将不得不修改你的代码,但这就是它的工作方式。更多信息请点击此处:https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection
您真正想要做的是使用class
而不是style
来处理此问题。原因是使用getElementsByClassName
可以非常容易地提取具有特定类的所有元素(注意:在IE 9及更高版本中)。
在不过分偏离您的方法的情况下(我确实提高了它的效率:),您的代码需要更改为:
CSS:
.firstClick {background-color: green;}
.secondClick {background-color: red;}
脚本:
var click = 0;
function res(zz,el) {
var currentlyClickedEls, currClass, divTarget;
if (click === 0) {
currClass = "firstClick";
divTarget = "starget";
click = 1;
}
else {
currClass = "secondClick";
divTarget = "etarget";
click = 0;
}
// get all the elements with the appropriate class
currentlyClickedEls = document.getElementsByClassName(currClass);
// remove that class from those elements
while (currentlyClickedEls.length > 0) {
currentlyClickedEls[0].className = "";
}
// add the class to the clicked element
el.className = currClass;
document.getElementById(divTarget).innerHTML = zz;
}
使用这种方法,单击时,您要做的第一件事就是找到类firstClick
或secondClick
的所有元素(基于click
的值),并移除该类。由于最多只能有一个,这使得要经过一个非常短的循环(但如果以某种方式发生,也会从多个元素中删除类)。
编辑:
因此,您不会在代码中注意到这一点,因为这两个类中的每一个都没有超过一个实例,但是,正如前面所指出的,我们正在处理DOM元素的LIVE集合,因此,当您从元素中删除类时(从中删除类的元素),就会从集合中掉出来。
例如,在表的第三次单击时,集合中会有一个元素由document.getElementsByClassName(currClass);
=HTMLCollection[td.firstClick]
(在控制台中)返回。但是,一旦从元素中删除了该类,它就不再符合条件,因此集合变为空(即HTMLCollection[]
)。
因此,尽管它适用于您的情况(因为它在i = 1
上停止,因为它仍然"不小于"集合的新长度(现在是0)。
然而,在其他情况下,情况可能并非如此。例如,如果返回了2个元素,在第一个元素的类被删除后,i
将变为1,但长度也将降至1,循环将停止,而不处理第二个元素。
因此,确实需要改变方法来正确处理这种行为。我通过更改这些行做到了这一点:
for (i = 0; i < currentlyClickedEls.length; i++) {
currentlyClickedEls[i].className = "";
到这些线路:
while (currentlyClickedEls.length > 0) {
currentlyClickedEls[0].className = "";
这样,删除其类的元素始终是集合中的第一个元素,while
循环在尝试删除该类之前进行检查以确保集合中仍有元素。
因此,长话短说,当处理HTML集合时,正如somethinghere所指出的,您正在处理DOM元素的实时集合,因此,如果您做出的更改会影响该集合中包含的单个元素,它将相应地更新集合,并且您需要能够在代码中对此进行说明。
- 专家Javascript迭代Thymelaf
- JavaScript迭代程序
- 使用Javascript迭代同级的最快方法是什么
- 是否可以通过Javascript迭代stdin中的每个单词
- if语句中的javascript迭代
- 如何使用 D3 javascript 迭代 JSON 文件中的数据
- 使用 Javascript 迭代以 HTML 显示多个图像
- JavaScript——迭代一系列问题(数组/对象)
- Javascript迭代问题
- 如何循环来自生成器的JavaScript迭代器
- 如何使用Javascript迭代DAO字段集合
- 用javascript迭代Django模板变量,通过不断变化的索引进行访问
- 如何在不使用javascript迭代的情况下找到数组中对象的索引
- Javascript-迭代嵌套对象,获取值和链式键
- 将json对象转换为数组,使用Javascript迭代ng-repeat
- 如何在jQuery中编写这个JavaScript迭代函数?
- 我如何使用JavaScript迭代这个对象
- Javascript迭代-颠倒顺序
- Javascript迭代器建议
- 在chrome控制台重新加载后保持Javascript迭代