检查图像加载完成情况

时间:2014-04-09 07:51:46

标签: javascript jquery complete

我有一个页面包含太多图像,这些图像被不等地划分为div个类photossetc。包含所有div的主div的ID为infscroll。开始时,每个div visibilityhiddenpositionabsolute,每divattributemyflagc其值为"notok"

我不想等待页面中的所有图像加载以显示div s因此不能选择加载到窗口,而是我想显示每个div内容独立加载。

这是我制作的jQuery / JavasScript代码:

function imagesloaded(){

    var infscrolllength=jQuery('#infscroll').find('.photossetc').length;
    // gets the numbers of divs
    var completedsts = 0;
    // variable for the number of divs that completed loading (set to 0)

        jQuery('#infscroll .photossetc').each(function(){
        // loops over the divs

            if(jQuery(this).attr("myflagc")=="notok"){
                var photosetclength = jQuery(this).find('img').length;
                var totalcomplete = 0;
                jQuery(this).find('img').each(function(){
                    if(this.complete){
                        totalcomplete++;
                    }
                })
                if(totalcomplete==photosetclength){
                    sortpho(jQuery(this));
                    completedsts++;
                }
            }
            else{
                completedsts++;
            }
    })
    if(infscrolllength != completedsts){
        imagesloaded();
    }

}

function sortpho(setselector){
    setselector.css({"position":"relative"});
    setselector.css({"visibility":"visible"});
    setselector.attr({"myflagc":"ok"});
}

jQuery(document).ready(function(){
imagesloaded();

});

然而,这段代码似乎并不适用于未知原因。然而,我注意到,如果我在alert函数中的任何位置添加imagesloaded()它可以正常工作,这通常意味着DOM尚未就绪,但由于我正在使用jQuery(document).ready它可以不是那样的。我还尝试在此块的末尾添加警报:

if(infscrolllength != completedsts){
    imagesloaded();
    alert("not completed yet");
}

我注意到它会多次触发,直到所有图像都被加载,这意味着代码是正确的,因此我不明白为什么没有alert它无法正常工作。

我知道我可以bind load事件发送到每个div,但load有缓存图片问题,所以我想避免使用它。

有解决方法吗?更重要的是,我想了解为什么这段代码不起作用。

更新:解决方法

Christian Landgren提到(见答案); JavaScript函数保持循环,防止页面呈现(即加载内容)。

我找到了一种解决方法来实现我想要的并且完全不依赖于.load方法。这是代码:

function imagesloaded(){
    var mysets=[];
    var setnbr=0;
    var iditer=0;
    jQuery('#infscroll .photossetc').each(function(){
        jQuery(this).attr({"id":"photosetn"+iditer});
    // giving a unique id to every div
        iditer++;
    })
    jQuery('#infscroll .photossetc').each(function(){
        var myset=[];
    // creating an array to hold the following info 0:id of div - 1: nbr of images in div - 2: nbr of images that finished loading
        myset[0]=jQuery(this).attr("id");
        myset[1]=jQuery(this).find('img').length;
        myset[2]=0;
        jQuery(this).find('img').each(function(){
            if(this.complete){  // for when the image is already cached or already loaded
                myset[2]=myset[2]+1;
            }
            else{ // for when the image isn't cached nor loaded yet
                jQuery(this).load(function(){
                    for(i=0;i<mysets.length;i++){
                        var myiset=mysets[i];
                        if(jQuery(this).parents('#infscroll .photossetc').attr("id")==myiset[0]){
                            myiset[2]=myiset[2]+1;
                            if(myiset[1]==myiset[2]){
                                jQuery('#'+myiset[0]).css({"position":"relative","visibility":"visible"});
                            }                                   
                            mysets[i]=myiset;
                        }
                    }
                })
            }
        })
        if(myset[1]==myset[2]){
            jQuery('#'+myset[0]).css({"position":"relative","visibility":"visible"});
        }
        mysets[setnbr]=myset;
        setnbr++;
    })
}

1 个答案:

答案 0 :(得分:0)

Javascript阻塞,这意味着你的循环将阻止所有javascript执行,直到满足该语句。当您添加警报时,至少让背景布局威胁在后台加载图像,直到您按OK并继续循环。

如果要跟踪已加载的图像数量,则需要在每个图像上附加onload事件,以独立更新loadcounter。

这样的事情:

var loadCounter = 0;

function allDone(){
  // all images are loaded.
}

function imageLoaded(){
  loadCounter++;
  if (loadCounter === $('img').length){
    allDone();
  }
}

$('img').on('onload', imageLoaded)

当你说你无法负担使用onload事件时,你能详细说明吗?您需要跟踪加载事件以了解何时加载所有加载事件。我已成功使用它,它也适用于缓存图像 - 根本没有任何问题。

另一个(不太柔和的)选项是全局检查带有间隔的加载计数。

另一个提示,如果你正在开发一个无限滚动,你需要使用一个队列来处理你开始加载的图像。目前无法中止单个图像请求。这意味着只要您将图像添加到DOM树中,它就会在布局引擎中排队,您无法从队列中删除该图像。

解决此问题的一种好方法是使用Async.queue机制并将onload事件附加到async next方法。