.forEach循环:使用变量

.forEach loop: use variable

本文关键字:变量 循环 forEach      更新时间:2023-09-26

我循环遍历一组16个id,并为每个id分配一个eventListener。我想向我的php文件发送一个数字(1代表第一个id,2代表第二个id,等等),但i似乎比我希望的更动态。每个id都发送17

klasses.forEach(function(klass){
    var svgElement = svgDoc.getElementById(klass); //get the inner element by id
    svgElement.addEventListener("mouseup",function(){
        $.ajax({
            type: "POST",
            url: "buildService.php",
            data: { "service" : i}
        }).done(function(msg){
            alert(lameArray[i]);
            $("#modalSpan").html(msg);
            $("#modmodal").modal();
        });
    });
    i++;
});

如何将每个设置为特定的数字?我也试过:

var lameArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
...
data: { "service" : lameArray[i]}

什么是i?问题是i是一个全局变量,或者是forEach周期之外的变量,所以当触发mouseup事件时,会使用istant的i值,而不是定义事件侦听器时的值。

请注意,由于您使用的是forEach,回调函数实际上是用第二个参数调用的,该参数就是计数器。所以你可以使用:

klasses.forEach(function(klass, i) {
    ...
});

现在,iforEach作用域中的一个变量,可用于您的目的。(forEach也用第三个参数调用回调函数,即集合本身——在您的情况下是klasses。)

注意:由于您使用的是jQuery,因此应该使用更"类似jQuery"的样式进行编码。因此,用这样的方式更改代码:

$.each(klasses, function(i, klass) {
    $("#" + klass).mouseup(function(){
        $.ajax({
            type: "POST",
            url: "buildService.php",
            data: {service: i + 1}
            ...
        });
    });
});

试试这个:

klasses.forEach(function(klass){
    (function(i) {
        var svgElement = svgDoc.getElementById(klass); //get the inner element by id
        svgElement.addEventListener("mouseup",function(){
            $.ajax({
                type: "POST",
                url: "buildService.php",
                data: { "service" : i}
            }).done(function(msg){
                alert(lameArray[i]);
                $("#modalSpan").html(msg);
                $("#modmodal").modal();
            });
        });
    })(i);
    i++;
});

当您需要迭代器索引时,不要使用forEach。并避免JQuery的.each。在绝大多数情况下,这是完全不必要的,而且它在每次迭代时都会触发一个回调函数,所以在IE中速度要慢得多。你可以用while编写一个完全懒惰/紧凑的循环。

var outerI = klasses.length;
while(outerI--){
    (function(i){
        i+=1;//doesn't affect outerI and you wanted 1-length so we add one.
        //I would personally just add 1 but it also adds clarity to the example
        //crap inside your forEach loop but without the i++
    })(outerI)
}

发生了什么:您告诉事件侦听器从外部范围引用i。所以,当那场比赛开始时,无论我是什么,你都会得到。

解决方案:将i的值传递到一个函数的范围中,在那里它变成了一个本地变量。带parens的业务只是一种懒惰的方式来定义、评估和执行匿名函数,这看起来像是一个步骤。函数通过第一个parens进行求值(使其可激发),因此第二个集合就像您放入函数定义的内部"i"参数中的arg。基本上,您通过将值传递给一个新的本地var来锁定所需的值。

关于while循环的注意事项:while(0)的计算结果为false,从而停止循环。如果你仔细想想,这很奇怪,因为1的长度比你想要的少一个。然而,在while(i-)中,我被求值,然后我被递减,所以在块内,长度为1到0,这非常适合数组表示法。要在其他运算符命中之前递减i,您通常会这样做——i,但它在惰性/高效while循环中很容易实现。