1

以下代码适用于我需要的所有东西,但 IE8 除外。一切都执行到 .load 上的闭包,返回函数永远不会被执行。

entries.resize_images = function(imgs) {
    for (var x = 0; x < imgs.length; x++) {
        var img = imgs[x];
        var pic_real_width, src;
        src = $(img).attr("src");
        $("<img/>") // Make in memory copy of image to avoid css issues
            .attr("src", src)
            .load(function(i) {
                return function () {
                    pic_real_width = this.width;
                    $(i).css("width", Math.round(pic_real_width * img_ratio));
                };
            }(img));
    }
};

任何帮助将不胜感激!

4

2 回答 2

0

以下是我将如何解决这个问题。我发现通读您的版本对于变量范围、传递参数和 jQuery 应用参数的特定组合有点令人困惑——这可能是您发现难以调试的原因。

  1. 如果您不需要,请避免使用闭包,它们可能很复杂,容易出错,如果您不小心,还会导致内存泄漏。
  2. 将 src 属性应用于图像时,我认为最好在这样做之前应用负载侦听器,但这可能只是虚构的,这只是我一直认为有意义的事情。
  3. 尽可能使用 jQuery 的强大功能,因为它让您的生活更轻松 :)
  4. 您不需要使用临时图像来避免 css 大小问题。
  5. IMG.complete 在图像缓存问题方面是您的朋友。

这使我想到以下内容:

var resizeImages = function( imgs, img_ratio ){
  /// not sure what you're passing to this function but the following
  /// should handle an array of images elms or a jQuery collection of images
  var images = ( imgs instanceof jQuery ? imgs : $().pushStack(imgs) );
  var resizeImage = function( img ){
    var cn, st, ow;
    /// make it so we can call this function in two ways
    if ( !img ) { img = $(this); }
    /// store items of the image
    cn = img.attr('class');
    st = img.attr('style');
    /// remove those items so they don't get in the way of original width
    img.attr('class','').attr('style','');
    /// get the original width
    ow = img.width();
    /// place back the things we've removed - changes wont render visibly
    /// till code execution finishes at the end of this function call.
    img.attr('class',cn);
    img.attr('style',st);
    /// apply the resize
    img.css('width', ow * img_ratio );
  }
  images.each(function(){
    var img = $(this);
    /// check if the image is already loaded, if so, resize directly
    if ( img.get(0).complete ) {
      resizeImage(img);
    }
    /// if the image isn't loaded yet, rely on an image load event
    else {
      img.load(resizeImage);
    };
  });
};

现在是不那么罗嗦的版本:)

var resizeImages = function( images, scale ){
  var cn, st, ow, resizeImage = function( img ){
    img = img || $(this);
    cn = img.attr('class');
    st = img.attr('style');
    ow = img.attr('class','').attr('style','').width();
    img.attr('class',cn).attr('style',st).css('width', ow * scale );
  }
  ( images instanceof jQuery ? images : $().pushStack(images) )
    .each(function(){
      ( this.complete ? resizeImage($(this)) : $(this).load(resizeImage) );
    });
};

$(function(){
  resizeImages( document.images, 0.5 );
});
于 2012-10-10T23:53:16.317 回答
-3

//编辑;在得知 jQuery 对 load 方法有魔力之后,我删除了我的答案并更改了我的代码以回复给出的评论。

我们将调用我们的魔法 3 次;添加一个 Timeout 以防我们很快在我们的初始调用中,以便如果它实际缓存在 img 加载时执行你的魔法或最新的。

var img=$("<img/>");
    img
        .attr("src", src)
        .load( function(ielem) {
                var called=false,
                    doMagic=function(e) {
                        if ( !called && this.complete ){
                            //your code
                            called=true;
                            clearTimeout(tout);                                
                        }
                    },
                    tOut=setTimeout(doMagic,100);
                //try a direct call first.. whynot? browser may be ready
                doMagic.call(ielem);
                return doMagic; 
            }(img[0])
        );

是的,正如你所知道的,我更像是原生的 javascripter 与 jQueryster。它没有真正经过测试,我只是在展示方式。欢迎评论。顺便提一句。只需+(new Date()).getTime()在您的 src 后面添加以重新获取并始终触发加载事件。如果你不介意带宽。

于 2012-10-10T17:58:50.400 回答