IE8没有调用闭包返回功能

时间:2012-10-10 17:52:41

标签: javascript jquery internet-explorer-8 closures

以下代码适用于我需要的所有内容,但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));
    }
};

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

以下是我如何处理这个问题。我发现阅读你的版本有点令人困惑,因为变量范围的特定组合,传递params和jQuery应用params - 这可能是你发现它很难调试的原因。

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

    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 );
    });
    

答案 1 :(得分:-3)

<强> //修改;在得知jQuery在load方法上做了魔术之后,我删除了我的答案并更改了我的代码以回复给出的评论。

我们会召唤我们的魔法3次;在我们的初始调用中添加一个超时,以便在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。它没有经过真正的测试,我只是在展示方式。欢迎评论。顺便说一句。只需在src后面添加+(new Date()).getTime()即可重新获取并始终触发加载事件。如果你不介意带宽。