窗口本身加载后如何触发加载事件?

时间:2016-06-19 22:51:33

标签: javascript jquery asynchronous single-page-application vue.js

我有一个框架(vue.js)在页面更改时插入一些图像(使用路由器,而不是真正的页面刷新)。直接加载时,我可以让页面显示加载屏幕:

loading = true;
$(window).on( 'load', function(){
    loading = false;
});

但是,如果页面已通过框架导航,则$(window).on('load')不会触发。这(我假设)是因为window已经加载,并且新图像的加载不再与窗口相关联。因此,loading = false永远不会触发,因为窗口已经加载。

这是一个极其简化的例子,但它说明了同样的观点:

//Loading the initial image, it works fine because it runs on window load.
console.log('Loading first image...')
$(window).on('load',function(){
    console.log('First image loaded');
});


$('button').on('click',function(){
  $('div').append('<img src="https://placekitten.com/200/300">');
  console.log('Loading extra image...');

  //This never triggers because the window is already loaded. 
  //I need something to trigger while the appended images are loading
  $(window).on('load',function(){
    console.log('Extra image loaded.');
  });

});

HTML:

<img src="https://placekitten.com/200/300">
<button>Click to load extra</button>
<div></div>

这是codepen

2 个答案:

答案 0 :(得分:1)

您可以使用唯一标识符为每个新图像添加.load()侦听器,并使用可用于在加载所有图像后运行函数的数组跟踪它们:

var loadingImages = [];
$('button').on('click',function(){

  //Get unique identifier + add to 'loading'
  var n = $('div').find("img").length;
  loadingImages.push(n);

  //Add image with unique classname
  $('div').append('<img data-n="'+n+'" src="https://placekitten.com/200/300">');

  //Attach load listener to new image
  $('div').find("img[data-n="+n+"]").load(function(){
    var n = $(this).attr('data-n');

    //Remove from 'loading'
    var index = loadingImages.indexOf(n);
    loadingImages.splice(index, 1);

    //if 'loading' empty, run function
    if(loadingImages.length==0){
        alert("Loaded All Images");
    }
  });
});

示例:JSFiddle

答案 1 :(得分:0)

@hakJav的解决方案是在正确的轨道上,但我需要进行一些编辑。他们很重要,我决定发表自己的答案。虽然他的回答并不一定能解决我的问题,但这是一个很好的代码,可以成为别人的解决方案。绝对检查两个答案。

这是我的JS函数(与原始帖子中的HTML一起使用):

$('button').on('click',function(){
        $('div').html('<img src="https://placekitten.com/200/400"><img src="https://placekitten.com/100/300">');
        var loadingImages = [];
        //Array of existing images
        var arrayOfImages = $('div').find('img');
        //Loops through array
        for(var i=0; i < arrayOfImages.length; i++){
            //Creates numerical value for each image, puts it in an array of images that are currently loading
            loadingImages.push(i);

            //For each image, add a load listener. Pass in i from the for loop so that it gets recorded in the event listener.
            $(arrayOfImages[i]).on('load', { currentImage: i }, function(event){
                //On load, removes the value from the array. Display which image loaded, for debugging.
                var index = loadingImages.indexOf(event.data.currentImage);
                loadingImages.splice(index, 1);
                console.log('image '+event.data.currentImage+' loaded');

                //Checks if the array is empty (last image loaded). If so, log all.
                if(loadingImages.length === 0){
                    console.log('all loaded');
                }
            });

        }

});

这具有能够遍历容器中已有的所有图像的优点,并且不一定依赖于能够在附加的html中指定数据属性。还可以处理图像的“组”,即同一HTML串中的多个图像。所以可能更具可扩展性。

这样做的缺点是,在完成第一组后,无法加载其他图像,例如.html().append()替换。原始图像仍然存在,完全加载,因此它们的值将保留在数组中。如果需要的话,可以通过一些操作来解决这个问题(我一次只需要加载一组图像)。

这是一个展示这个的代码: http://codepen.io/Blue_Dragon360/pen/GqjyGJ?editors=1010