4

完成 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

4 回答 4

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 });
 }
于 2009-09-22T00:49:30.090 回答
1

我的猜测是 cvi_instant.add() 正在对传递给它的值进行一些递增或迭代。尝试这样做 - 它更容易,我相信它会解决您的问题:

function done() {
  var e = document.getElementsByName('pic');
  for (pic in e) { cvs_instant.add(pic, { shadow: 75, shade: 10 }); }
}
于 2009-09-22T00:35:52.800 回答
1

嗨,我遇到了同样的问题。我的脚本跳过了所有其他元素。我终于通过在我的循环中将变量名从 i 更改为 k 来解决它。我的猜测是,getElementsByTagName 在内部使用变量 i 来跟踪它在活动节点列表中的位置,并以某种方式泄漏到程序员界面。所以它是一个错误!:-)

于 2010-12-08T00:28:29.160 回答
0

- 编辑:

我在下面声称的所有内容似乎都是完全错误的。我把这个留在这里作为任何有相同想法的人的观点:) 我在 FF3 中测试过。我很想声称我曾经在 IE 中看到过这种行为,但也许是很多年前的事了(想想看,可能是 7 年前)。我的记性可能很差:)

- 老的:

稍微扩展一下我的猜测,如果结果是准确的:

从内存中,如果您不声明变量('var ...'),它将使用其他地方的变量。

因此,未经测试,此代码:

for(var k = 0; k < 2; k++){
    f();
    alert("k: " + k);
}

function f () {
  k++;
}

应该表现出相同的行为。我认为 TML 的解决方案非常好,从“防御性编码”的角度来看,我的分析结果是正确的。

于 2009-09-22T00:39:49.533 回答