我几乎没有类似的文本框。当我运行下面给出的验证脚本时,其中一个不会在第一次受到影响,即使它是空的。我想知道原因。
以下是HTML:
<input type='text' class='txt' value="" />
<input type='text' class='txt' value="" />
<input type='text' class='txt' value="" />
<input type='button' onclick='validate()' value='validate' />
JS:
function validate() {
var txts = document.getElementsByClassName('txt');
for (var i = 0; i < txts.length; i++) {
if(txts[i].value === "")
txts[i].className = 'txtError';
}
}
和CSS:
.txt {
border:1 px solid green;
}
.txtError {
border:1 px solid blue;
background:red;
}
这可能是一个愚蠢的错误,但我多次盯着它,目前我的眼睛没有抓到任何东西。我也在不同的浏览器中尝试过它。
这是展示问题的JSfiddle。
旁注:我不是在寻找另一个验证脚本,我只是想知道为什么第二个文本框会逃脱验证。
答案 0 :(得分:4)
因为getElementsByClassName
会返回实时收藏集。这意味着当您更改DOM时,它会在您下面更新。因此,当您从第一个框中删除txt
类时(将其替换为txtError
,您突然有一个大小为2而不是3的可枚举。
要修复它,您可以使用数组切片技巧将实时集合转换为常规数组
var txts = Array.prototype.slice.call(document.getElementsByClassName('txt'), 0);
然而,有更好的方法来实现你在这里做的几乎所有事情。所以不是讨论这个问题的地方,但是一旦你开始工作,请继续将其发布在the codereview stackexchange上以获得反馈。
答案 1 :(得分:0)
这似乎是一个奇怪的问题,我无法完全解释这个问题。但是在调试和单步执行代码时,每次更新其中一个元素的类名时,txts的集合都会递减。因此,这是我能想到修复它的唯一方法。基本上你有相同的东西,但我开始使用txts数组的最后一个元素,而不是第一个元素。
function validate() {
var txts = document.getElementsByClassName('txt');
for (var i = txts.length - 1; i >= 0; i--) {
if (txts[i].value === "") txts[i].className = 'txtError';
}
}
答案 2 :(得分:0)
我认为问题出现了,因为你完全改变了这个类,而不仅仅是添加一个类;至少,它解决了我的问题。
这里&#39; sa jsfiddle我创建的{{3}}通过将行为更改为更像jQuery&#39; .addClass()
方法的方式工作得很好 - 我设置了.className = 'txt txtError'
而不仅仅是txtError
将其更改为{{1}}。