javascript循环仅适用于所有其他元素

leo*_*ora 3 javascript asp.net ajax loops getelementsbyname

在完成ajax查询后,我有以下javascript

我的所有图片都有名字="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 });
     }
 }
Run Code Online (Sandbox Code Playgroud)

我的目标是使用此库应用图像边框:

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 });
     }
Run Code Online (Sandbox Code Playgroud)

bob*_*nce 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 });
 }
Run Code Online (Sandbox Code Playgroud)

另一个简单的解决方案是,如果您知道在每次调用时总是要从列表中删除元素,那么:

 var e= document.getElementsByName("pic");
 while (e.length>0) {
     cvi_instant.add(e[0], { shadow: 75, shade: 10 });
 }
Run Code Online (Sandbox Code Playgroud)

当循环体可以对列表执行任何操作时,需要最通用的解决方案,例如插入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 });
 }
Run Code Online (Sandbox Code Playgroud)