JavaScript的循环只适用于所有其他元素 [英] javascript loop only applying to every other element

查看:119
本文介绍了JavaScript的循环只适用于所有其他元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下后,我完成一个ajax查询下面的JavaScript

我所有的图片都NAME =PIC

 <脚本类型=文/ JavaScript的>
 函数来完成(){
     变种E = document.getElementsByName(PIC);
     警报(e.length);
     对于(VAR I = 0; I< e.length;我++){
         cvi_instant.add(E [I],{阴影:75,灯罩:10});
     }
 }
 

我的目标是应用周围使用这个库的图像边框:

http://www.netzgesta.de/instant/

的问题是,由于某种原因,这种工作,但它似乎只适用于具有各种其他图像,而不是每次一片。任何线索为什么code以上将跳过所有其他元素?

编辑:我添加了循环警报,它并正确地去0,1,2,3,4,5,6。

 的(VAR I = 0; I< e.length;我++)
     {
         警报(ⅰ);
         cvi_instant.add(E [I],{阴影:75,灯罩:10});
     }
 

解决方案
  

它似乎只适用于每两个图像,而不是每一个

这是破坏性的迭代的经典标志。

考虑会发生什么,如果像我猜,功能 cvi_instant.add 替换指定的元素 PIC 与一些其它元素或元素

getElementsByName 返回一个'活'节点列表:这是每一个你做出改变的DOM时间保持最新。因此,如果收到五行,您的通话后, cvi_instant.add 它现在包含只有四个:第一个节点不见了,节点1-4已经向下移动到位置0 -3。

现在你周围的循环着呢。 我++ ,所以我们正在寻找的元素,但1元1现在是什么最初元件2!我们跳过了原始元素1,我们将继续跳过所有其他元素,直到我们达到的(现在的一半长)列表的末尾。

变更的列表的同时作为迭代它会导致这样的问题。如果迭代里面的过程实际上的添加的元素列表中,你甚至可以得到一个无限循环!

速战速决是向后遍历循环。现在你做的最后一个元素首先,让所有其他元素在原位置,并没有造成跳绳:

 变种E = document.getElementsByName(PIC);
 对于(VAR I = e.length;我 - 大于0){
     cvi_instant.add(E [I],{阴影:75,灯罩:10});
 }
 

另一种简单的解决方案,如果你的知道的你总是会被从名单上每次调用删除元素是:

 变种E = document.getElementsByName(PIC);
 而(e.length大于0){
     cvi_instant.add(E [0],{阴影:75,灯罩:10});
 }
 

当你的循环体可以做的最通用的解决方案是必要的什么应用于列表,如在开始插入名为 PIC 新元素该文件或删除从中间的其他元素。它是速度较慢,但​​总是安全的榜上无名的静态副本从工作:

 函数Array_fromList(L){
     变种一个= [];
     对于(VAR I = 0; I< l.length;我++)
         a.push(升[I]);
     返回;
 }

 变种E = Array_fromList(document.getElementsByName(PIC));
 对于(VAR I = 0; I< e.length;我++){
     cvi_instant.add(E [I],{阴影:75,灯罩:10});
 }
 

i have the following javascript below after i finish an ajax query

all of my images have 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 });
     }
 }

my goal is to apply an image border around using this library:

http://www.netzgesta.de/instant/

the problem is that for some reason this works but it only seem to apply to every other picture instead of every one. any clue why the code above would skip every other element??

EDIT: I added an alert in the loop and it does correctly go 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 });
     }

解决方案

it only seem to apply to every other picture instead of every one

That's a classic sign of destructive iteration.

Consider what happens if, as I'm guessing, the function cvi_instant.add replaces the element named pic with some other element or elements.

getElementsByName returns a ‘live’ NodeList: it is kept up to date every time you make a change to the DOM. So if it had five elements before, after your call to cvi_instant.add it now contains only four: the first node is gone and nodes 1–4 have moved down to positions 0–3.

Now you go around the loop again. i++, so we're looking at element 1. But element 1 is now what was originally element 2! We skipped the original element 1, and we will continue skipping every other element until we reach the end of the (now half as long) list.

Altering a list at the same time as iterating it causes this kind of problem. If the process inside the iteration actually adds elements to the list you can even get an infinite loop!

The quick fix is to iterate the loop backwards. Now you do the last element first, leaving all the other elements in their original positions and causing no skipping:

 var e= document.getElementsByName("pic");
 for (var i= e.length; i-->0;) {
     cvi_instant.add(e[i], { shadow: 75, shade: 10 });
 }

Another simple solution if you know you're always going to be removing the element from the list on each call is:

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

The most general solution is needed when your loop body can do anything to the list, such as inserting new elements named pic at the start of the document or removing other elements from the middle. It is slightly slower but always safe to make a static copy of the list to work from:

 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 });
 }

这篇关于JavaScript的循环只适用于所有其他元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆