在Angular中延迟加载图像的最简单方法是什么?

时间:2013-11-26 22:45:46

标签: angularjs

我有一个应用程序,允许通过键盘的右/左箭头键对大文本数据集进行分页。显示的数据也包含图像。

我希望在用户快速分页数据时延迟加载这些图像1-2秒。

一旦用户停在某个页面,所有图像都应该“懒洋洋地”加载。

我试图让这个小提琴适应我的应用程序但没有成功(见下文)。 http://jsfiddle.net/boneskull/UfrhH/3/

我的控制器代码

$scope.delay_images = function() {
$timeout(function() {
    return true;
}, 2000);
};

查看代码

<tbody>
  <tr>
    <td style='text-align:left;padding-right:40px; height:250px;width:{{100 / panel.size}}%' ng-repeat="event in data| slice:panel.offset:panel.offset+panel.size">
    <h4>{{event._source.Price}} {{event._source.Currency}}</h4>
    <img ng-show="delay_images" ng-animate="{show: 'show'}" style='height:100px' ng-src="/img/{{event._source.image_paths}}"/><br /><h6>{{event._source.Title}}</h6>
    <button ng-click="build_search(event._source)" ng-show='event._source.ClusterID' type="button" class="btn btn-primary">More like this</button> 
    </td>
  </tr>
</tbody>

我对angular.js相当新,所以任何可以指导我进入正确方向的提示都非常感谢。

谢谢!

更新

这是基于接受的答案的部分工作代码。顺便说一句,它还实现了keydownevent的延迟。

现在代码使用ng-show来隐藏和显示图像。我意识到这种方法存在问题,因为它在用户分页时会在后台触发大量的图像资源请求。

所以最好的方法是将当前的解决方案与第二个解决方案结合起来替换src =属性。

我该怎么做?我正在从周围的div中捕获keydownevent,所以我没有直接处理图像。有没有办法使用角度js访问一类元素?就像使用jquery选择器一样?

var lastFire = 0;
$scope.changeIndex = function($event) {

    if($event.keyCode == 37 || $event.keyCode == 39){

    var cFire = new Date();
    // cancel old timeout
    if ($scope.panel.timeoutId) {
        $timeout.cancel($scope.panel.timeoutId);
    }

    // $event.keyCode...
    if ((cFire - lastFire) / 1000 > 0.3){  

        // hide images to start with
        $scope.panel.imagesVisible = false;


        if ($event.keyCode == 37 && $scope.panel.offset > 0){
        $scope.panel.offset = $scope.panel.offset - 10;
        //$scope.get_data();
        lastFire = cFire;
        $scope.panel.timeoutId = $timeout(function() {
            $scope.panel.imagesVisible = true;
            $scope.panel.timeoutId = undefined;
        }, 1000);

        }
        if ($event.keyCode == 39 && $scope.panel.offset < $scope.data.length - 10){
        $scope.panel.offset = $scope.panel.offset + 10;
        //$scope.get_data();
        lastFire = cFire;
        $scope.panel.timeoutId = $timeout(function() {
            $scope.panel.imagesVisible = true;
            $scope.panel.timeoutId = undefined;
        }, 1000);
        }

    }
    else{
        $scope.panel.timeoutId = $timeout(function() {
            $scope.panel.imagesVisible = true;
            $scope.panel.timeoutId = undefined;
        }, 1000);
    }

}


};

3 个答案:

答案 0 :(得分:4)

我会制作一个自定义指令。这是我的头脑,未经测试,但这样的事情应该有效:

myApp.directive('ngSlowSrc', function($timeout){
return{
    restrict: 'A',
    link: function(scope, element, attrs){
        $timeout(function() {
            element.src = attrs.ngSlowSrc;
        }, 2000);
    }
}
});

现在只需按照以下方式调用图片:<img ng-slow-src="myimage.jpg" >

这种方式的工作方式是等待2秒钟来设置图像的src。

答案 1 :(得分:2)

我认为最简单的方法是在分页时处理它。假设这是您调用页面的功能:

$scope.changeOffset = function(offset) {
    $scope.panel.offset = offset;

    // cancel old timeout
    if ($scope.panel.timeoutId) {
        $timeout.cancel($scope.panel.timeoutId);
    }

    // hide images to start with
    $scope.panel.imagesVisible = false;

    $scope.panel.timeoutId = $timeout(function() {
        $scope.panel.imagesVisible = true;
        $scope.panel.timeoutId = undefined;
    }, 2000);
});

然后页面上的所有图像都可以使用标记:

<img ng-show="panel.imagesVisible" ...

答案 2 :(得分:0)

工作解决方案......

使用了包含jquery的angular中的元素方法。 还包括在超时之间的apply方法,以使ui体验更流畅。 感谢您的投入。

   var lastFire = 0;
        $scope.changeIndex = function($event) {

            if($event.keyCode == 37 || $event.keyCode == 39){

            var cFire = new Date();
            // cancel old timeout
            if ($scope.panel.timeoutId) {
                $timeout.cancel($scope.panel.timeoutId);
            }

            // $event.keyCode...
            if ((cFire - lastFire) / 1000 > 0.5){  

                if ($event.keyCode == 37 && $scope.panel.offset > 0){
                $scope.panel.offset = $scope.panel.offset - 10;
                //$scope.get_data();
                lastFire = cFire;
                $scope.panel.timeoutId = $timeout(function() {
                    $scope.$apply(function () {
                        angular.forEach(angular.element('.productImage'), function(value, key){
                            var elem = angular.element(value);
                            elem.attr('src',elem.attr('ng-slow-src'));
                        });
                        $scope.panel.timeoutId = undefined;
                    });
                }, 1000);

                }
                if ($event.keyCode == 39 && $scope.panel.offset < $scope.data.length - 10){
                $scope.panel.offset = $scope.panel.offset + 10;
                //$scope.get_data();
                lastFire = cFire;
                $scope.panel.timeoutId = $timeout(function() {
                    $scope.$apply(function () {
                        angular.forEach(angular.element('.productImage'), function(value, key){
                            var elem = angular.element(value);
                            elem.attr('src',elem.attr('ng-slow-src'));
                        });
                        $scope.panel.timeoutId = undefined;
                    });
                }, 1000);
                }

            }
            else{
                $scope.panel.timeoutId = $timeout(function() {
                    $scope.$apply(function () {
                        angular.forEach(angular.element('.productImage'), function(value, key){
                            var elem = angular.element(value);
                            elem.attr('src',elem.attr('ng-slow-src'));
                        });
                        $scope.panel.timeoutId = undefined;
                    });
                }, 1000);
            }

        }


        };