jQuery Retina图像替换循环

时间:2013-11-15 21:57:24

标签: jquery retina-display

我正在编写一个循环遍历页面上所有图像的脚本,如果该文件存在,则用“Retina ready”版本替换它们。问题是当循环遍历每个图像时,它会改变变量:

retinaText = "@2x";

$("img").each(function(){
    filename = $(this).attr("src");
    ext = "."+filename.substr((Math.max(0, filename.lastIndexOf(".")) || Infinity) + 1);
    filesource = filename.split(ext)[0];
    retinaImage = filesource + retinaText + ext;

    //check if images exists

    $.ajax({
        url:retinaImage,
        type:'POST',
        error: function(){  },
        success: function(){  
            //file exists
            //replace image with retina ready image 
            //$(this).attr("src",retinaImage);
        }
    });
});

我设置了一个测试环境,其中第一个图像有替换,而其他图像没有,但是由于循环继续遍历图像,变量会发生变化。

如果图像设置如下:

<img src="image1.jpg" />
<img src="image2.jpg" />
<img src="image3.jpg" />
<img src="image4.jpg" />

此图像存在于同一目录中:

<img src="image1@2x.jpg" />

脚本最终试图用“image4 @ 2x”替换image4,因为retinaImage变量和$(this)已经改变了。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

您声明变量的方式将它们置于全局范围内。例如,retinaImage成为全局变量,并在.each()的每次迭代中进行修改。

使用var关键字创建局部变量。例如:

$("img").each(function(){
    var filename = $(this).attr("src");
    var ext = "."+filename.substr((Math.max(0, filename.lastIndexOf(".")) || Infinity) + 1);
    var filesource = filename.split(ext)[0];
    var retinaImage = filesource + retinaText + ext;
    //check if images exists

    // ADDED: keep reference to current image
    var currentImage = $(this);

    $.ajax({
        url:retinaImage,
        type:'POST',
        error: function(){  },
        success: function(){  
            //file exists
            //replace image with retina ready image 

            // currentImage refers to the correct image, and retinaImage refers to that image's retina URL
            currentImage.attr("src",retinaImage);
        }
    });
});

局部变量将其范围保持在当前函数中,以及closures