img onload在IE7中不能很好地工作

时间:2008-10-13 20:18:53

标签: javascript html internet-explorer image

我的webapp中有一个img标记,它使用onload处理程序来调整图像大小:

<img onLoad="SizeImage(this);" src="foo" >

这在Firefox 3中工作正常,但在IE7中失败,因为传递给SizeImage()函数的图像对象由于某种原因的宽度和高度为0 - 也许IE在完成加载之前调用该函数? 。在研究这个问题时,我发现其他人对IE也存在同样的问题。我还发现这不是有效的HTML 4.这是我们的doctype,所以我不知道它是否有效:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

是否有合理的解决方案可以在加载图像时调整图像大小,最好是符合标准的图像?该图像用于用户上传自己的照片,几乎可以是任何尺寸,我们希望以最大150x150的速度显示它。如果您的解决方案是在上传时调整图像服务器端的大小,我知道这是正确的解决方案,但我禁止实现它:(必须在客户端完成,并且必须在显示时完成。

感谢。

编辑:由于我们的应用程序的结构,在文档的onload中运行此脚本是不切实际的(接近不可能)。我只能合理地编辑图像标记及其附近的代码(例如我可以在它下方添加<script>)。此外,我们已经拥有Prototype和EXT JS库......管理层更愿意不必添加另一个(一些答案提示jQuery)。如果可以使用这些框架解决这个问题,那就太棒了。

编辑2 :不幸的是,我们必须支持Firefox 3,IE 6和IE 7.我们也希望支持所有基于Webkit的浏览器,但因为我们的网站目前不支持它们,我们可以容忍只适用于Big 3的解决方案。

8 个答案:

答案 0 :(得分:7)

如果您不必支持IE 6,则可以使用此CSS。

yourImageSelector {
    max-width: 150px;
    max-height: 150px;
}

答案 1 :(得分:6)

IE7正在尝试在完全呈现DOM树之前调整图像大小。你需要在document.onload上运行它...你只需要确保你的函数可以处理传递对不是“this”的元素的引用。

或者......我希望这不是一个可以冒犯的攻击...... jQuery让这样的东西变得非常简单。

编辑回应编辑1:

您可以将document.onload(runFunction);放在身体任何位置的任何脚本标记中。它仍会等到文档加载后才能运行该函数。

答案 2 :(得分:4)

我注意到Firefox和Safari无论如何都会在新图像上发出“加载”事件,但IE 6&amp; 7只有在实际上必须从服务器获取图像时才会“加载” - 他们不会t如果图像已经在本地缓存中。我玩了两个解决方案:

1)每次给图像一个唯一的http参数,Web服务器忽略,如

<img src="mypicture.jpg?keepfresh=12345" />

这有一个缺点,它实际上打败了缓存,所以你浪费带宽。但它可以解决问题,而无需使用JavaScript。

2)在我的应用程序中,需要加载处理程序的图像由JavaScript动态插入。我不使用附加图像,而是构建处理程序,而是使用此代码,该代码在Safari,FF和IE6&amp; 7。

document.body.appendChild(newPicture);
if(newPicture.complete){
    doStuff.apply(newPicture);
}else{
    YAHOO.util.Event.addListener(newPicture, "load", doStuff);
}

我正在使用YUI(显然),但你可以使用框架中的任何工作来附加处理程序。函数doStuff期望在附加到受影响的IMG元素的情况下运行,这就是我以 .apply 样式调用它的原因,您的里程可能会有所不同。

答案 3 :(得分:3)

jQuery代码。但是用其他框架拨打电话很容易。真有帮助。

var onload = function(){ /** your awesome onload method **/ };
var img = new Image();
img.src = 'test.png';

// IE 7 workarond
if($.browser.version.substr(0,1) == 7){
    function testImg(){
        if(img.complete != null && img.complete == true){ 
            onload();
            return;
        }
        setTimeout(testImg, 1000);
    }
    setTimeout(testImg, 1000);
}else{
    img.onload = onload
}

答案 4 :(得分:2)

我这样做的方法是使用jQuery做类似的事情:

$(document).load(function(){
    // applies to all images, could be replaced 
    //by img.resize to resize all images with class="resize"
    $('img').each(function(){
        // sizing code here
    });
});

但我不是javascript专家;)

答案 5 :(得分:1)

如果你真的陷入困境,

setTimeout()可能是一种解决方法。只需将其设置为2或3秒 - 或者在预期加载页面之后。

编辑:你可能想看看this article - 关于IE内存泄漏的底部...

答案 6 :(得分:1)

  

编辑:由于我们的应用程序的结构,   这是不切实际的(接近   不可能)在中运行此脚本   文件的载入。

总是可以向window.onload(或任何事件)添加处理程序,即使其他框架,库或代码将处理程序附加到该事件。

<script type="text/javascript">
function addOnloadHandler(func) {
    if (window.onload) {
        var windowOnload = window.onload;
        window.onload = function(evt) {
            windowOnload(evt);
            func(evt);
        }
    } else {
        window.onload = function(evt) {
            func(evt);
        }
    }
}

// attach a handler to window.onload as you normally might
window.onload = function() { alert('Watch'); };

// demonstrate that you can now attach as many other handlers
// to the onload event as you want
addOnloadHandler(function() { alert('as'); });
addOnloadHandler(function() { alert('window.onload'); });
addOnloadHandler(function() { alert('runs'); });
addOnloadHandler(function() { alert('as'); });
addOnloadHandler(function() { alert('many'); });
addOnloadHandler(function() { alert('handlers'); });
addOnloadHandler(function() { alert('as'); });
addOnloadHandler(function() { alert('you'); });
addOnloadHandler(function() { alert('want.'); });
</script>

This answer使用addOnloadHandler()的{​​{1}}代码版本略有不同。但我在测试中发现attachEvent似乎并不能保证处理程序按照您添加它们的顺序触发,这可能很重要。提供的函数保证处理程序按添加的顺序触发。

请注意,我将attachEvent传递给添加的事件处理程序。这不是绝对必要的,代码应该在没有它的情况下工作,但是我使用一个库,它希望将事件传递给evt处理程序,并且除非我将它包含在我的函数中,否则代码将失败。

答案 7 :(得分:0)

您可以执行以下操作:

var img = new Image();
img.src = '/output/preview_image.jpg' + '?' + Math.random();
img.onload = function() {
  alert('pass')
}