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 回呼び出します。最初の呼び出しですぐにタイムアウトになる場合に備えて、実際にキャッシュされている場合は、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 に答える