火狐下jquery更换图像src后获取图像尺寸异常

时间:2012-7-2 作者:剧中人

近来小剧在用jquery尝试实现flash站里非常酷的的图像播放器效果。喜欢它是因为整个图像浏览器是以浏览器窗口为显示区域,并且富有动感的渐入渐出,和动态缩放更具酷炫效果很吸引人。

现在小剧写的js版的图像浏览器已经初现雏形,部分bug仍在发现修正中,目前能够兼容ie6及大多数主流浏览器,现已嫁接到小剧客栈里。体验图像浏览器效果

这里我并不是想说图像浏览器是如何实现的,而是说说我在图像浏览器开发的过程中发现了火狐的一个出乎意料的现象。

出现的问题

为了效果更容易控制,图像浏览器前端显示的图像始终是一个img标签,在点击左右箭头时更换img标签的src属性,以达到切换图像的效果。切换过图像之后再获取此图像的宽度和高度,为图像框做动画。

其实代码远比这要复杂,下面是我对出现的问题简化后的代码:

$(document).ready(function(){
  $('img').click(function(){
    $(this).attr('src','images/1.gif');
    alert($(this).width());
  });
});

上面代码很简单,就是点击网页中任意的图片后为其更换图片,紧接着alert出新图片的宽度。小剧测试了下,ie从6到9,和chrome提示的都是新图片的宽度,唯独火狐提示的是原图片的宽度。

然而小剧此次要实现的效果就是在更换图片结束后,立即获取新图片的尺寸,以供其他动画只用,火狐的这种情况对小剧所做的图像浏览器无疑是一个致命的打击。

为了解决这个问题,小剧开始思考,可能是火狐虽然更换了图像,但未被立即加载,或者加载时间略长于执行下一段代码的时间,因而获取到的尺寸仍然是原图片的尺寸。(以上仅是小剧的猜测而已)。

于是我尝试着通过延迟获取图像尺寸来解决,下面是我修改后的代码:

$(document).ready(function(){
  $('img').click(function(){
    var i = $('img').index(this);
    $(this).attr('src','images/1.gif');
    setTimeout(function(){
      alert($('img').eq(i).width());
    },1);
  });
});

开始小剧是给setTimeout的时间设为500毫秒,很给力在火狐中获取尺寸就正常了,然后小剧在逐渐缩小时间,直至为1的时候仍然有效。后来再发布到网上测试,仍然有效果。

下面说下小剧对这种情况提供的解决方案

不要在更改图像后立即获取图像尺寸,使用setTimeout来延迟获取。

虽然引起这样问题出现的确切尚不清楚,但延迟获取确实是行之有效的解决方案,因为1毫秒虽然在视觉上与0毫秒没有任何差异,但却足以让所有代码执行很多遍。因此用延时来解决这类问题应该很合适。

当然,以上仅仅是小剧的发现和提出的解决方法,可能你有更好的解释或解决方案,也欢迎你与小剧分享。