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

发布于 2024-08-05 14:02:35 字数 785 浏览 6 评论 0原文

下面有以下 javascript

在我完成 ajax 查询后,我的所有图像都有 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 });
     }

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

几度春秋 2024-08-12 14:02:35

它似乎只适用于所有其他图片,而不是所有图片

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

考虑一下,如果正如我猜测的那样,函数 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 });
 }

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 });
 }
蒗幽 2024-08-12 14:02:35

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

function done() {
  var e = document.getElementsByName('pic');
  for (pic in e) { cvs_instant.add(pic, { shadow: 75, shade: 10 }); }
}

My guess is that cvi_instant.add() is doing some incrementing or iteration on the values passed to it. Try doing this instead - it's easier, and I believe it will fix your problem:

function done() {
  var e = document.getElementsByName('pic');
  for (pic in e) { cvs_instant.add(pic, { shadow: 75, shade: 10 }); }
}
怎樣才叫好 2024-08-12 14:02:35

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

Hi I came across the same problem.
My script was skipping every other
element. I finally solved it by simply
changing the variable name from i to
k in my loop. My guess is therefor
that the variable i is used by
getElementsByTagName internally to
keep track of where it is in the
live nodelist and is leaking out
to the programmers interface somehow.
So its a bug! :-)

梦情居士 2024-08-12 14:02:35

-- 编辑:

我在下面声明的所有内容似乎完全错误。我把这一点留在这里,作为任何有同样想法的人的一个观点:)我在 FF3 中进行了测试。我很想说我在 IE 中见过一次这种行为,但也许是很多年前了(想想看,可能是 7 年前)。我的记忆可能很差:)

- 老:

稍微扩展一下我的疯狂猜测,如果它被证明是准确的:

从记忆中,如果你不声明一个变量('var ...')它会使用一个来自其他地方的。

因此,无需测试,此代码:

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

function f () {
  k++;
}

应该显示相同的行为。我认为TML的解决方案相当不错,从“防御性编码”的角度来看,我的分析结果是正确的。

-- EDIT:

All of what I claim below appears to be totally wrong. I leave this here as a point for anyone who thought the same :) I tested in FF3. I would love to claim that I saw this behaviour once, in IE, but maybe it was many years ago (come to think of it, it was probably 7 years ago). My memory is probably bad :)

-- OLD:

To slightly expand on my wild guess, if it turns out to be accurate:

From memory, if you don't declare a variable ('var ...') it'll use one from somewhere else.

Thus, without testing, this code:

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

function f () {
  k++;
}

Should show the same behaviour. I think TML's solution is quite nice, from a 'defensive coding' point of view, it my analysis turns out to be correct.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文