问题:

项目中遇到一个需求是图片服务不是很稳定,截图不一定能出来,所以增加错误处理,如果不出来就隐藏。

问题是想优化一下,降级处理,如果截图不出来,就换一张截图,实在不行再隐藏。

再有就是因为是响应式页面,有些图片不一定看得见,所以优化的目标还有一个是只加载看得见的图片。

解决办法:

img标签里不写src属性(不能写src=”“,浏览器会去会把当前网页重新载入一次。),把真实图片链接放在另外一个属性里:_src. 这样js可以通过判断是否需要显示之后,把需要显示的图片的src属性写上_src上的值。这里是为了配合响应式页面做得处理。

如果这张图片加载失败了的话,就看看img标签里另外一个属性_bak里的值,这里存了一个第二选择的图片地址。跟上面同样的处理方式,只不过,需要重新绑定onerror事件。这样写还是无法第二次触发onerror事件。还需要把赋予src值这一步延时处理。

为什么重新绑定及延时处理我没有找到原因,我猜是因为浏览器对onerror的优化及图片需要一个赋予的过程才能触发onerror事件,这也许也是浏览器优化。

另外,错误处理完了,要把事件删除,否则IE会循环执行onerror事件直到栈溢出(IE你这是何苦呢……)

以下是完整代码:

//JQuery 环境下。
var delayTimer;
var backImgAttrName = '_bak';
var evtError = function( imgDom ){ 
	var backImgSrc = imgDom.attr( backImgAttrName );
	if ( backImgSrc ){
		//重新绑定
		imgDom.bind('error',function () {
            evtError( $(this) );
        }); 
        //延时处理
        delayTimer = setTimeout(function(){
        	imgDom.attr('src',backImgSrc).removeAttr( backImgAttrName );
        },500);
	}else{
		//隐藏
		imgDom.css('visibility','hidden');
		//如果图片外面是a标签,确保a标签站位与图片同等大小
    	var aTag = imgDom.parent();
    	aTag.attr('href') && aTag.css('display','inline-block');
    	//destroy
    	imgDom.unbind('error');
    	delayTimer && clearTimeout( delayTimer );
	}
};
$.each(domArray,function(i,v){
	var imgDom = $(v).find('img');
    if( imgDom && $(v).is(":visible") ){
        var _src  =  imgDom.attr('_src'); 
        _src && imgDom.attr('src',_src);
        imgDom.removeAttr('_src');
    }
    imgDom.bind('error',function () {
    	evtError( $(this) );
    }); 
});

参考资料:

img的onerror事件(瑕疵+解决办法)

img 图片加载失败后,重复加载问题代码(可限定次数)

记于2014年02月28日 EOF