I have an app that allows paginating through a large text dataset via the keyboard's right/left arrow keys. The data that is displayed, also contains images.
I would like to delay the loading of these images for 1-2 seconds while the user is paginating through the data quickly.
As soon as the user stops at a certain page, all images should be "lazily" loaded.
I tried to adapt this fiddle to my app without success (see below). http://jsfiddle.net/boneskull/UfrhH/3/
my controller code
$scope.delay_images = function() {
$timeout(function() {
return true;
}, 2000);
};
view code
<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>
I am fairly new to angular.js so any tips that can guide me into the right direction are greatly appreciated.
Thanks!
UPDATE
This is a partially working code based on the accepted answer. BTW, it also implements a delay for the keydownevent.
Right now the code uses ng-show to hide and show images. I realized that this approach is problematic because it triggers a lot of image resource requests in the background while the user is paging.
So the best would be to combine the current solution somehow with the second solution replacing the src= attribute.
How would I go about that? I am catching the keydownevent from a surrounding div, so I have no direct handle to the images. Is there a way to access a class of elements with angular js? Just like with a jquery selector?
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);
}
}
};
I'd make a custom directive. This is off the top of my head, untested, but something like this should work:
myApp.directive('ngSlowSrc', function($timeout){
return{
restrict: 'A',
link: function(scope, element, attrs){
$timeout(function() {
element.src = attrs.ngSlowSrc;
}, 2000);
}
}
});
now just make your image calls like this: <img ng-slow-src="myimage.jpg" >
The way this works is it just waits 2 seconds to set the src of your image.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With