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

时间:2009-09-22 00:17:48

标签: asp.net javascript ajax loops getelementsbyname

在完成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 });
     }

4 个答案:

答案 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的解决方案相当不错,从“防御性编码”的角度来看,我的分析证明是正确的。