【问题标题】:img onload doesn't work well in IE7img onload 在 IE7 中无法正常工作
【发布时间】:2010-09-16 23:12:37
【问题描述】:

我的 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 中运行此脚本是不切实际的(几乎不可能)。我只能合理地编辑图像标签和它附近的代码(例如我可以在它下面添加一个&lt;script&gt;)。此外,我们已经有 Prototype 和 EXT JS 库......管理层宁愿不必添加另一个(一些答案建议使用 jQuery)。如果可以使用这些框架解决这个问题,那就太好了。

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

【问题讨论】:

  • 问题:SizeImage() 是否只是将图像大小调整为 150x150?我有不同的解决方案,都比下面的更好,但这取决于你需要 SizeImage() 做什么。
  • @Eric:不,它应该保持图像的纵横比。此外,如果原始图像小于 150x150,则根本不应该调整大小(我不想拉伸和图像)。

标签: javascript html internet-explorer image


【解决方案1】:

你可以这样做:

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

【讨论】:

    【解决方案2】:

    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
    }
    

    【讨论】:

      【解决方案3】:

      编辑:由于我们应用的结构, 这是不切实际的(接近于 不可能)在 文档正在加载中。

      始终可以将处理程序添加到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 使用attachEvent 与我的addOnloadHandler() 代码版本略有不同。但是我在测试中发现attachEvent 似乎并不能保证处理程序按照您添加它们的顺序触发,这可能很重要。提供的函数保证处理程序按添加的顺序触发。

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

      【讨论】:

        【解决方案4】:

        我注意到 Firefox 和 Safari 无论如何都会在新图像上触发“加载”事件,但 IE 6 和 7 仅在它们确实必须从服务器获取图像时才会触发“加载”——如果图像已经在本地缓存中。我玩了两种解决方案:

        1) 每次都给图像一个唯一的 http 参数,网络服务器会忽略,比如

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

        这有一个缺点,它实际上会破坏缓存,所以你在浪费带宽。但它可能会解决问题,而不必搞砸你的 JavaScript。

        2) 在我的应用程序中,需要加载处理程序的图像由 JavaScript 动态插入。我不只是附加图像,然后构建一个处理程序,而是使用这段代码,它在 Safari、FF 和 IE6 和 7 中测试良好。

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

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

        【讨论】:

        • 非常感谢您的回复!我自己从来没有想过这个!
        • 谢谢。在 HTML5 游戏中使用资源加载器时遇到了恼人的问题...(测试高度 > 0 而不是完整的,但相同的想法)
        【解决方案5】:

        setTimeout() 如果你真的被卡住了,可能是一种解决方法。只需将其设置为 2 或 3 秒 - 或在页面预计加载之后。

        编辑:您可能想看看this article - 一直在底部关于 IE 内存泄漏...

        【讨论】:

          【解决方案6】:

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

          或者...我希望这不是一个易燃的进攻... jQuery 让这样的事情变得非常非常容易。

          编辑以响应编辑 1:

          您可以将document.onload(runFunction); 放在任何脚本标签中,在正文中的任何位置。它仍然会等到文档加载完毕才能运行该函数。

          【讨论】:

          • 通常在加载之前尝试修改dom的一部分会导致可怕的“操作中止”消息。
          • @Steve,用 jQuery 做“真的很容易”吗?我在我的项目中使用 jQuery,但这并不容易! jQuery 的文档同意即使使用 jQuery 加载事件,IE 也无法正确处理 onLoad/请参阅link - 段落“与图像一起使用时加载事件的注意事项。”。我使用了 jQuery,但仍然必须编写一整段代码来支持 IE。
          【解决方案7】:

          如果你不需要支持 IE 6,你可以使用这个 CSS。

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

          【讨论】:

          • 这真是个好主意...我什至不知道这是一个可用的 CSS 选项。不幸的是,我们需要支持 IE6。我更新了问题以提及这一点。
          • 这里是如何支持 IE6:
          【解决方案8】:

          我会这样做的方式是使用 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 专家 ;)

          【讨论】:

            猜你喜欢
            • 2017-10-12
            • 1970-01-01
            • 2023-03-13
            • 1970-01-01
            • 2012-06-12
            • 2011-11-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多