在完成ajax查询后,我有以下javascript
我的所有图片都有name =“pic”
<script type="text/javascript">
function done() {
var e = document.getElementsByName("pic");
alert(e.length);
for (var i = 0; i < e.length; i++) {
cvi_instant.add(e[i], { shadow: 75, shade: 10 });
}
}
我的目标是使用此库应用图像边框:
http://www.netzgesta.de/instant/
问题在于,由于某种原因,这种方法有效,但它似乎只适用于所有其他图片而不是每一张图片。任何线索为什么上面的代码会跳过其他所有元素?
编辑:我在循环中添加了一个警报,它正确地执行了0,1,2,3,4,5,6。 。
for (var i = 0; i < e.length; i++)
{
alert(i);
cvi_instant.add(e[i], { shadow: 75, shade: 10 });
}
答案 0 :(得分:7)
它似乎只适用于所有其他图片而不是每一张
这是破坏性迭代的经典标志。
如果正如我猜测的那样,函数cvi_instant.add
用一些其他元素替换名为pic
的元素,请考虑会发生什么。
getElementsByName
返回“实时”NodeList:每次对DOM进行更改时都会保持最新状态。因此,如果它之前有五个元素,在您调用cvi_instant.add
之后它现在只包含四个:第一个节点消失,节点1-4向下移动到0-3位置。
现在你再次绕圈。 i++
,所以我们正在看元素1.但元素1现在是元素2!我们跳过原始元素1,我们将继续跳过所有其他元素,直到我们到达(现在一半长)列表的末尾。
在迭代它的同时更改列表会导致此类问题。如果迭代中的进程实际上将元素添加到列表中,您甚至可以获得无限循环!
快速解决方法是向后迭代循环。现在,您首先执行最后一个元素,将所有其他元素保留在原始位置,不会导致跳过:
var e= document.getElementsByName("pic");
for (var i= e.length; i-->0;) {
cvi_instant.add(e[i], { shadow: 75, shade: 10 });
}
另一个简单的解决方案,如果你知道你总是会在每次调用时从列表中删除元素:
var e= document.getElementsByName("pic");
while (e.length>0) {
cvi_instant.add(e[0], { shadow: 75, shade: 10 });
}
当你的循环体可以对列表进行任何时,需要最通用的解决方案,例如在文档的开头插入名为pic
的新元素或从中删除其他元素中间。稍微慢一点但总是安全的,可以使列表的静态副本起作用:
function Array_fromList(l) {
var a= [];
for (var i= 0; i<l.length; i++)
a.push(l[i]);
return a;
}
var e= Array_fromList(document.getElementsByName("pic"));
for (var i= 0; i<e.length; i++) {
cvi_instant.add(e[i], { shadow: 75, shade: 10 });
}
答案 1 :(得分:1)
我的猜测是cvi_instant.add()正在对传递给它的值进行一些递增或迭代。尝试这样做 - 它更容易,我相信它会解决你的问题:
function done() {
var e = document.getElementsByName('pic');
for (pic in e) { cvs_instant.add(pic, { shadow: 75, shade: 10 }); }
}
答案 2 :(得分:1)
您好我遇到了同样的问题。 我的剧本正在跳过其他人 元件。我终于简单地解决了它 将变量名称从i更改为 k在我的循环中。我的猜测就是这样 变量i被使用 内部的getElementsByTagName 跟踪它在哪里 实时节点列表并且正在泄漏 以某种方式到程序员界面。 所以这是一个错误! : - )
答案 3 :(得分:0)
- 编辑:
我在下面声称的所有内容似乎完全错误。我把这个留在这里作为任何想法相同的人:)我在FF3中测试过。我很乐意声称我曾经在IE浏览器中看到过这种行为,但也许是很多年前(想想它,可能是7年前)。我的记忆可能很糟糕:))
- OLD:
如果事实证明是准确的,那么稍微扩展我的猜测:
从内存中,如果你没有声明变量('var ...'),它将使用来自其他地方的变量。
因此,未经测试,此代码:
for(var k = 0; k < 2; k++){
f();
alert("k: " + k);
}
function f () {
k++;
}
应该显示相同的行为。我认为TML的解决方案相当不错,从“防御性编码”的角度来看,我的分析证明是正确的。