jQuery,悬停方法和闭包

时间:2009-05-11 13:24:53

标签: javascript jquery closures

一直试图围绕功能范围包围Javascript关闭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帖子中进行作用域的想法。似乎工作正常,但在第一个悬停函数中抛出一个未定义的数组值,我想因为它是一个内部函数(硬编码图像源在那里正常工作)。

1 个答案:

答案 0 :(得分: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”,您将声明并访问全局变量。 (如果这是你的预期行为,那么我道歉。)