LoginSignup
1
0

More than 3 years have passed since last update.

複数の画像が読み込まれた"後"に処理を実行させる

Last updated at Posted at 2020-03-12

やりたかったこと

  1. 画像を含んだ要素をappendする
  2. appendされた画像がすべてロードされたあとに関数を実行する
  3. その関数で、imgを含めた要素の高さを取得する

つまづいたところ

通常ならappendしたらそのまま次の処理でheight()すれば、要素の高さを取得することができるが、画像をappendしたときは画像がロードされたのを見届けなければ、高さがうまくとれない。

それは、画像を子孫に含んだ要素も同じです。

リロードするとキャッシュされたものを拾ってくれるので、一見するとうまく処理されているように見えるトラップつきだった。

失敗コード

appendしてすぐにmatch_height_byChildElems('.js-add-faceImgs');しているコードです。

$(function () {

    var thumbnails = ['taro', 'jiro', 'saburo', 'shiro', 'goro', 'tanjiro']

    for (var i = 0; i < thumbnails.length; i++) {
        var iconURL = '/img/icon_face_' + thumbnails[i] + '.png';
        html = '<li>';
        html += '<img src="' + iconURL + '" alt="">';
        html += '</li>';
        var $elm = $(html);
        $('.js-add-faceImgs').append($elm);
    }

    match_height_byChildElems('.js-add-faceImgs'); // ココ!
});


/**
 * 子要素の最大の高さを計算して、親要素の高さを指定する
 * @param {String} className 親クラス名*/
function match_height_byChildElems(className) {
    var maxHeight = 0;

    $(className).children().each(function(){
        var thisHeight = $(this).height();
        console.log($(this), thisHeight)

        maxHeight = maxHeight <= thisHeight ? thisHeight : maxHeight;
    });
    $(className).height(maxHeight);
}

解決方法

追加した要素の長さとloadCounterの値が同じ = 処理完了!

として、そのときにmatch_height_byChildElems('.js-add-faceImgs')を呼び出しています。
これで、setTimeout()など当てずっぽう数字ではなく、指定のimgすべてがロード完了したときに関数を呼び出すことができます。

成功コード

$('.js-add-faceImgs img').each(function(){~~を追加して、imgのロード完了をカウントしています。

$(function () {

    var thumbnails = ['taro', 'jiro', 'saburo', 'shiro', 'goro', 'tanjiro']

    for (var i = 0; i < thumbnails.length; i++) {
        var iconURL = '/img/icon_face_' + thumbnails[i] + '.png';
        html = '<li>';
        html += '<img src="' + iconURL + '" alt="">';
        html += '</li>';
        var $elm = $(html);
        $('.js-add-faceImgs').append($elm);
    }

    // imgのロードが完了したらマッチハイトさせる
    // ココ!
    var loadCounter = 0;
    $('.js-add-faceImgs img').each(function(){
        $(this).load(function(){
            loadCounter++;
            if (loadCounter === $('.js-add-faceImgs img').length) {
                match_height_byChildElems('.js-add-faceImgs');
            }
        });
    });
});


/**
 * 子要素の最大の高さを計算して、親要素の高さを指定する
 * @param {String} className 親クラス名*/
function match_height_byChildElems(className) {
    var maxHeight = 0;

    $(className).children().each(function(){
        var thisHeight = $(this).height();

        maxHeight = maxHeight <= thisHeight ? thisHeight : maxHeight;
    });
    $(className).height(maxHeight);
}

余談

こう書いたほうがスッキリするかもです。


// imgのロードが完了したらマッチハイトさせる
var loadCounter = 0;
$('.js-add-faceImgs img').each(function(){
    $(this).load(function(){
        loadCounter++;
        var loadComplete = (loadCounter === $('.js-add-faceImgs img').length);
        if (loadComplete) match_height_byChildElems('.js-add-faceImgs');
    });
});
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0