5

我正在为我的网站做一个无限滚动的脚本:

$(window).scroll(function(){
  if($(window).scrollTop() == $(document).height() - $(window).height()){
    ...
    $.ajax({
      ...
      success: function(json) {if(json.success){
        ...
        // here I append an Ajax @response with a new element to my existing HTML
        $("#mindIndexSummaryFirst").append(json.items1);
        $("#mindIndexSummarySecond").append(json.items2);
        $("#mindIndexSummaryThird").append(json.items3);
        // here I try to check whether all images are loaded
        $("#mindIndexSummary img").on('load', function(){
          // and I need to call two functions on loaded element
          // hoverImg() need the loaded image to calculate the height
          $('.pi-hover-img'+json.course).hoverImg();
          $(".popup3").tooltip();
        });
      }
    ...
  });

加载的 HTML 元素是这样的:

<div class="page-item pi-hover-img  pi-normal">
  <a class="overlayPop" href="#">
  <a class="item_uri" id="course153" href="#">
    <img src="/public/file/course/image/153-course.png" class="pi-item-image">
  </a>
  <a href="#" class="popup5 hide-text" style="display: none;">
    <img src="/public/file/account/image/282-user.jpeg" class="item_image">
  </a>
  <a class="popup action-button big_interested " id="course_153" href="javascript:;" style="top: -162.5px; left: 83.5px; display: none;"> Mi interessa</a>
  <a href="javascript:;">Description</a>
  <a class="popup4 hide-text" href="javascript:;">Preview</a>
  <span class="popup2" style="display: none;">1€&lt;/span>
  <a href="/course/153/gestire-un-pubblico">
    <h2 style="top: 320px;">Gestire un pubblico</h2>
    <span class="rfloat pi-icon">
      <img src="/public/img/site_icon/video_course_black.png">
    </span>
    <div class="clearfix"></div>
  </a>
</div>

我加载了 5 个元素,15 个图像,但加载的元素可能更少。

问题是我的函数被调用了不止一次(我用警报测试了这个)并且我不确定在图像加载后调用该函数是否安全。

如果有人遇到同样的情况,请给我一些建议(PS 我为我糟糕的英语道歉)。

4

4 回答 4

6
$("#mindIndexSummary img").on('load', function(){ });

将处理程序附加到与查询匹配的每个图像 - 因此每个图像在加载时都会触发该函数 - 当所有图像都完成加载时不会触发一次。

您必须跟踪已加载的图像才能确定它们是否已全部加载。

沿着:

var noOfImages = $("#mindIndexSummary img").length;
var noLoaded = 0;

$("#mindIndexSummary img").on('load', function(){ 

    noLoaded++;
    if(noOfImages === noLoaded) {
        handleAllLoaded();
    }

});
于 2013-05-10T15:45:03.627 回答
0

这是我在类似情况下使用的解决方案的粗略版本。numLoaded每次load执行该方法时都会更新,这使您可以检查预测 ( numImage) 是否等于加载的图像总量。

var img =  $( '#mindIndexSummary' ).find( 'img' )
  , numImage = img.length;

img.on( 'load', function(){

    var self = $( this )
      , numLoaded  = self.attr( 'data-loaded', true ).length;

    self.attr( 'data-loaded', true );

    if( numImages === numLoaded ) 

    funcToCall();   


});

此外,您可以更进一步并data在父元素上设置一个属性,这将允许您根据其值触发/终止其他事件。

var parent = $( '#mindIndexSummary' )
  , img =  $( '#mindIndexSummary' ).find( 'img' )
  , numImage = img.length;

img.on( 'load', function(){

    var self = $( this )
      , numLoaded  = self.attr( 'data-loaded', true ).length;

    parent.attr( 'data-load', 'loading' );
    self.attr( 'data-loaded', true );

    if( numImages === numLoaded ) 

    parent.attr( 'data-load', 'complete' );
    funcToCall();   


});

if( parent.attr('data-load').slice( 0, 7 ) === 'loading' )
do something else
于 2013-05-10T16:07:31.703 回答
0

图像上的加载事件有点不可靠(请参阅http://api.jquery.com/load-event/上的 Jquery 文档)。也就是说,可以通过单独检查每个选定图像上的加载事件来组装解决方案。有可能图像在执行时已被缓存或已加载。在这种情况下,图像元素应该有一个“.complete”属性。

我制作了一个小的 jQuery 插件来说明该方法(无论如何还有更完整的):

(function($) {
    $.fn.imagesLoaded = function(options) {
        var images = this.find("img"), 
            loadedImages = [], 
            options = options;

        images.each(function(i, image) {
            function loaded() {
                loadedImages.push(this);
                if(options.imageLoaded) {
                    options.imageLoaded(this);    
                }
                if(loadedImages.length == images.length) {
                    if(options.complete) {
                        options.complete(loadedImages);    
                    }
                }
            }

            if(image.complete || image.complete === undefined) {
                // Image is already loaded
                loaded.call(image);               
            } else {
                // Image is not loaded yet, bind event
                $(image).load(loaded);
            }
        });
    }
})(jQuery);

该插件接受带有两个回调的哈希,一个在每次加载图像时触发(图像作为参数传递),另一个在所有图像加载时触发(图像数组作为参数传递)。

$("#element-containing-images").imagesLoaded({
    imageLoaded: function(image) {
       console.log("Image loaded:", image); 
    }, 
    complete: function(images) {
        console.log("All images loaded:", images);
    }
});

它并没有包含所有的怪癖,但它应该给你一个大致的想法。我在http://jsfiddle.net/GYJGK/上做了一个小演示。

于 2013-05-10T16:36:56.547 回答
0

这是对如何创建一个全局变量(一个数组)的描述,该变量将跟踪加载的每个单独的图像。这样,您可以使用回调函数主动检查所有图像何时加载。

var image_state_array = new Array(false, false, false, false, false, false, false, false, false, false);

数组中的每个位置都将跟踪已加载的图像。因此,例如,如果已加载 10 个图像列表中的第 2 个图像,则数组将如下所示(记住数组索引从 0 开始):

var image_state_array = new Array(false, false, true, false, false, false, false, false, false, false);

假设您有一个基于某些用户交互动态重新加载的图像列表(例如,用户单击刷新以获取一组新图像以供选择)。加载完所有图像后,您想提醒用户图像已加载(或调用其他类型的函数)。首先为即将加载的图像设置一个 onload 事件。

//get image 0

var image = document.getElementsByClassName("search_images")[0];

//track the image load state 

image.onload = function(){
      trackImageLoadState(0); //note that 0 is the image index from the list of elements 
}

接下来像往常一样设置图像的来源。这将触发 onload 并调用该函数。

//set the source of the image, 

    image.src = desireImagePNG;

跟踪图像加载状态将添加图像已加载到 image_state_array,跟踪 image0 已加载。在它记录 image0 已经加载后,它会遍历 image_state_array 并计算返回的图像有多少已经加载。如果加载了足够多的图像,它将执行您尝试实现的任何功能。在此示例中,我正在淡出加载屏幕。

    function trackImageLoadState(numImage){
      //debug print
      //console.log("numImage: " + numImage);

      //set the array image value to true of the passed in index 
      image_state_array[numImage] = true;

      //debug print
      //console.log("image_state_array[numImage] " + image_state_array[numImage] );

      var loadedImagesCount = 0;

      //loop through the array and count the amount of images that have loaded
      for(var counter2 = 0; counter2 < image_state_array.length; counter2++){
        //debug print
        //console.log("image_state_array[counter] " + image_state_array[counter2] + "counter" + counter2 );

        if(image_state_array[counter2]){
          loadedImagesCount++;
        }
      }

      //debug print
      //console.log("loadedImagesCount: " + loadedImagesCount);

      //if the amount of images required to be loaded has been met, execute function. If you want to know when all images have been loaded, you need to set the if statement condition to the total count of images. For example:
if(loadedImagesCount>10){} if you have 10 images. 

  if(loadedImagesCount>5){

    //fade out the loading screen - any other function will work here as well
    fadeOutMainLoadingScreen();

  }

}

请记住,每次再次调用操作时都必须重置全局变量。这可以如下所示完成:

//reset the global variable array to track the new load of images 

for(var i = 0; i < image_state_array.length; i++){
  image_state_array[i] = false;
}

这是通过回调函数和全局变量跟踪哪些图像已加载的有效方法。请发表评论,因为我知道它可能会得到改进并变得更有活力。谢谢!

于 2017-03-15T16:14:50.920 回答