3

一段时间以来一直在努力解决 Javascript 闭包问题,试图将大脑包裹在函数范围内,但我认为它们正在包裹着我。我看过很多帖子(Nyman 的帖子最有帮助),但显然还是不明白。尝试在 jQuery 中的悬停方法上运行循环。需要悬停功能来最终触发一个以上的动作,但现在很高兴让它们使用单​​个图像交换。

$(document).ready(function() {

    imageSource = []; 
    imageSource[0] = 'images/img0.png'  //load 0 position with "empty" png
    imgArea = [];

    for (var i=1; i<11; i++) {

        (function( ){  //anonymous function for scope

            imageSource[i] = 'images/img' + i + '.png';
            imgArea[i] = '#areamap_Img' + i;

            // running console.log here gives expected values for both

            $(imgArea[i]).hover(   //imgArea[i] (selector) works correctly here

                function() {
                    $('#imgSwap').attr('src',imageSource[i]);  // imageSource[i] is undefined here
                },
                function() {
                    $('#imgSwap').attr('src','images/img0.png');
                });

        })(); // end anonymous function and execute

    }; // for loop

}); 

尝试使用匿名函数从另一个 jQuery 帖子中确定范围的想法。似乎工作正常,但在第一个悬停函数中为数组值抛出了一个未定义的值,我猜是因为它是一个内部函数(硬编码的图像源在那里正常工作)。

4

1 回答 1

11

您的闭包确实存在问题,这与您对 var 的使用有关i。由于您的匿名函数没有本地版本i,因此它使用的是上面函数的版本。i但是,当它稍后尝试访问时, i== 11(因为这就是导致循环终止的原因)。要解决此问题,您需要i在每个匿名函数中声明一个本地版本,如下所示:

for (var i=1; i<11; i++) {

    (function( ){  //anonymous function for scope                
            var index = i; // The important part!

            // It's not technically necessary to use 'index' here, but for good measure...
            imageSource[index] = 'images/img' + index + '.png';
            imgArea[index] = '#areamap_Img' + index;

            $(imgArea[index]).hover(

                    function() {
                            $('#imgSwap').attr('src',imageSource[index]);  // Here's where `index` is necesssary.
                    },
                    function() {
                            $('#imgSwap').attr('src','images/img0.png');
                    });

    })(); // end anonymous function and execute

}; // for loop

此外,您的代码中存在一个小问题,您应该修复它只是为了更好地衡量。您没有正确访问局部变量;你应该使用:

var imageSource = []; 
var imageSource[0] = 'images/img0.png'  //load 0 position with "empty" png
var imgArea = []

如果没有“var”,您将声明和访问全局变量。(如果这是您的预期行为,那么我道歉。)

于 2009-05-11T13:33:03.057 回答