Image loaded event in for ng-src in AngularJS
JavascriptHtmlAngularjsJavascript Problem Overview
I have images looking like <img ng-src="dynamically inserted url"/>
. When a single image is loaded, I need to apply iScroll refresh() method so that to make image scrollable.
What is the best way to know when an image is fully loaded to run some callback?
Javascript Solutions
Solution 1 - Javascript
Here is an example how to call image onload http://jsfiddle.net/2CsfZ/2/
Basic idea is create a directive and add it as attribute to img tag.
JS:
app.directive('imageonload', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('load', function() {
alert('image is loaded');
});
element.bind('error', function(){
alert('image could not be loaded');
});
}
};
});
HTML:
<img ng-src="{{src}}" imageonload />
Solution 2 - Javascript
I modified this a little so that custom $scope
methods can be called:
<img ng-src="{{src}}" imageonload="doThis()" />
The directive:
.directive('imageonload', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('load', function() {
//call the function that was passed
scope.$apply(attrs.imageonload);
});
}
};
})
Hope someone finds it VERY useful. Thanks @mikach
The doThis()
function would then be a $scope method
Solution 3 - Javascript
@ Oleg Tikhonov: Just updated the previous code.. @ mikach Thanks..)
app.directive('imageonload', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('load', function() {
alert('image is loaded');
});
element.bind('error', function(){
alert('image could not be loaded');
});
}
};
});
Solution 4 - Javascript
My answer:
var img = new Image();
var imgUrl = "path_to_image.jpg";
img.src = imgUrl;
img.onload = function () {
$scope.pic = img.src;
}
Solution 5 - Javascript
Just updated the previous code..
<img ng-src="{{urlImg}}" imageonload="myOnLoadImagenFunction">
and directive...
.directive('imageonload', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('load', function() {
scope.$apply(attrs.imageonload)(true);
});
element.bind('error', function(){
scope.$apply(attrs.imageonload)(false);
});
}
};
})
Solution 6 - Javascript
Basically this is the solution I ended up using.
$apply() should only be used by external sources in the right circumstances.
rather then using apply, I've thrown the scope updating to end of the call stack. Works as good as "scope.$apply(attrs.imageonload)(true);".
window.app.directive("onImageload", ["$timeout", function($timeout) {
function timeOut(value, scope) {
$timeout(function() {
scope.imageLoaded = value;
});
}
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('load', function() {
timeOut(true, scope);
}).bind('error', function() {
timeOut(false, scope);
});
}
};
}]);