如何按顺序加载对象数组的图像?

时间:2016-10-14 14:30:45

标签: javascript html angularjs arrays ng-repeat

我有一个看起来像这样的数组:

$scope.myArray = [
    {name:   'some name',
     age:    '20',
     imgURL: 'some/url.png'
    },
    {name:   'another name',
     age:    '53',
     imgURL: 'some/url2.png'
    }
]

数组中有大约500个对象,并且所有对象都以ng-repeat的形式加载到页面上,如下所示:

<div data-ng-repeat="person in myArray">
    <img ng-src="{{person.imgURL}}"/>
</div>

现在,如果用户位于具有良好无线连接的桌面上,则相对较小的图像会在页面上快速加载。但是我最后一次尝试使用手机时......它非常粗糙,因为屏幕只有大约6张图像的空间,而且它们没有任何特定的顺序可以将它们加载到页面上。结果,用户盯着黑屏直到它们向下滚动,或直到顶部的图像加载。

我一直试图通过使用承诺找出迫使这些图片按顺序加载的好方法,但还没有运气好。有没有人对我如何能够这样做有任何想法?谢谢!

对于那些可能很好奇的人来说,后端只是一个json文件,它通过角度服务加载,如下所示:

  $scope.generatePeople = function(){
      getPeopleService.getPeople().then(function(response){
          $scope.myArray = response;
      }, function(error){
      });
  };

.service('getPeopleService', ['$http', '$q', '$rootScope', function($http, $q, $rootScope){
    var getPeople = function() {
        var deferred = $q.defer();
        $http.get('people.json').success(function (data, status, headers, config) {
            deferred.resolve(data);
        }).error(function(data, status, headers, config){
            deferred.reject(status);
        });
        return deferred.promise;
    }
    return({
        getPeople: getPeople
    })
}])

2 个答案:

答案 0 :(得分:0)

实现此目的的唯一方法是将这些图像转换为base64,然后将它们作为一个json响应发送。这不是您的代码的问题,而是浏览器加载图像的方式。另一种方法是通过ajax请求每个图像,并在另一个图像完成后请求另一个图像

另一种方法是,如果您不希望用户盯着空白屏幕,那么在图像后面的元素中有一个微调器,并且当图像凹陷时,微调器就会被覆盖。

答案 1 :(得分:0)

正如我在评论中所提到的,您可以选择创建一系列Promise.race,如下所示;

&#13;
&#13;
function racer(proms){
  Promise.race(proms)
         .then(val => { var idx = images.indexOf(val);
                        console.log(val);   // doSomething(val);
                        proms.splice(idx,1);
                        images.splice(idx,1);
                        proms.length && racer(proms);
                      });
}

var images = [...Array(10)].map((_,i) => ({imageNo : i, loadTime: ~~(Math.random()*9001)+1000})),
  promises = images.map(img => new Promise((resolve,reject) => setTimeout(_ => resolve(img),img.loadTime)));
    
racer(promises);
&#13;
&#13;
&#13;

在这个模型示例中,我们有一个图像对象,在1-10秒内随机加载。因此,我们生成一个包含10个这些图像的数组,并将其映射到promises数组中。每场比赛结束后,我们都会从promisesimages数组中挑选出胜利者并开始新的比赛。

现在您已经按照从最快到最慢的顺序获取图像,所以您需要做的就是在收到它们时从上到下将它们插入到页面中。