加载列表(带图像)时添加回调函数

时间:2014-11-16 10:56:35

标签: javascript jquery html

文档准备好后,我通过ajax调用加载此图像列表:

$.ajax({
        url:'mysite.it/ajax/list_filter.php',
        data:data,
        type:'POST'
    }).done(function(data){
        var response = $.parseJSON(data);
        var people = '';
        if(response.success){ 
            if(response.showcase){
                $.each((response.showcase),function(index,item){
                    people += '<li>';                
                    people += '<img src="'mysite.it/pict_thumbs/' +item.pool_user_pict+ '">';
                    people += '<label>' +item.username+ '</label>';                       
                    people += '</li>';
                });
            }
        }
});

由于列表可能很大,我想在加载并显示所有图像并且列表准备就绪后才调用回调函数。
我怎么能这样做?

2 个答案:

答案 0 :(得分:1)

function loadImages(images, callback) {
    var length, count, check, i, img;

    length = images.length;
    count = length;

    check = function () {
        if (--count === 0) {
            callback();
        }
    };

    for (i = 0; i < length; i++) {
        img = new Image();

        img.onload = check;
        img.onerror = check;

        img.src = images[i]
    }
}

var images = [], html = '';

$.each(response.showcase, function(index, item) {
    html += '<li>';                
    html += '<img src="mysite.it/pict_thumbs/' + item.pool_user_pict + '">';
    html += '<label>' + item.username + '</label>';                       
    html += '</li>';

    images.push(item.pool_user_pict);
});

loadImages(images, function () {
    $('#some-element').html(html);
});

JSFiddle:http://jsfiddle.net/v2dyfdyu/

答案 1 :(得分:0)

我认为async library在这里很合适。

$.ajax({
        url:'mysite.it/ajax/list_filter.php',
        data:data,
        type:'POST'
    }).done(function(data){
        var response = $.parseJSON(data);
        var people = $('<ul />');
        if(response.success && response.showcase) {
            async.map(response.showcase, function(item, done) {
                var img = new Image();

                //we now install callbacks to certain events
                img.addEventListener('load', function () {
                    done(null, {
                        img: img,
                        username: item.username
                    });
                });

                img.addEventListener('error', function () {
                    done(true);
                });

                //this will kick image loading
                img.src = 'http://mysite.it/pict_thumbs/' + item.pool_user_pict;
            }, function (err, results) {
                if(err) {
                    //images weren't loaded correctly, handle this whatever you like
                    console.error('Something went wrong');
                    return;
                }

                //here you now know that every image you wanted is loaded
                results.forEach(function (data) {
                    var li = $('<li />');
                    li.append(data.img);
                    li.append($('<label />', {
                        html: data.username
                    }));

                    people.append(li);
                });
            });
        }
    });

我使用的方法async.map以它调用它的方式工作,它是数组的每个元素的第二个参数(迭代器),然后等到调用所有done函数。 done函数是一个函数,它将错误作为其第一个参数(null,如果没有错误)和异步操作的结果 - 在我们的例子中,一个加载的图像元素,被推送到一个新的阵列。

当调用了所有done时,async会调用第三个参数(回调),传递一个错误(如果没有错误则传递null)和一个数组,所有异步回调。然后我们可以迭代它们并将图像和用户名附加到html元素。

这是演示它的小提琴(使用保存在response变量中的假数据):http://jsfiddle.net/wxx6veqb/