我正在编写一个循环遍历页面上所有图像的脚本,如果该文件存在,则用“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)已经改变了。
非常感谢任何帮助。
答案 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。