30

I've been searching for an answer to simple but not trivial question: What is a right way to catch image' onload event in Angular only with jqLite? I found this question , but I want some solution with directives.
So as I said, this is not accepted for me:

.controller("MyCtrl", function($scope){ // ... img.onload = function () { // ... } 

because it is in controller, not in directive.

3 Answers 3

40

Here's a re-usable directive in the style of angular's inbuilt event handling directives:

angular.module('sbLoad', []) .directive('sbLoad', ['$parse', function ($parse) { return { restrict: 'A', link: function (scope, elem, attrs) { var fn = $parse(attrs.sbLoad); elem.on('load', function (event) { scope.$apply(function() { fn(scope, { $event: event }); }); }); } }; }]); 

When the img load event is fired the expression in the sb-load attribute is evaluated in the current scope along with the load event, passed in as $event. Here's how to use it:

HTML

<div ng-controller="MyCtrl"> <img sb-load="onImgLoad($event)"> </div> 

JS

 .controller("MyCtrl", function($scope){ // ... $scope.onImgLoad = function (event) { // ... } 

Note: "sb" is just the prefix I use for my custom directives.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Sam, this works like a charm, I think I'll leave the sb prefix to give you credit.
Thumbs up for a scale-able solution that works well without jqLite (which was removed from Angular 2)
31

Ok, jqLite' bind method doing well its job. It goes like this:

We are adding directive' name as attribute in our img tag . In my case , after loading and depending on its dimensions , image have to change its class name from "horizontal" to "vertical" , so directive's name will be "orientable" :

<img ng-src="image_path.jpg" class="horizontal" orientable /> 

And then we are creating simple directive like this:

var app = angular.module('myApp',[]); app.directive('orientable', function () { return { link: function(scope, element, attrs) { element.bind("load" , function(e){ // success, "onload" catched // now we can do specific stuff: if(this.naturalHeight > this.naturalWidth){ this.className = "vertical"; } }); } } }); 

Example (explicit graphics!): http://jsfiddle.net/5nZYZ/63/

Comments

7

AngularJS V1.7.3 Added the ng-on-xxx directive:

<div ng-controller="MyCtrl"> <img ng-on-load="onImgLoad($event)"> </div> 

AngularJS provides specific directives for many events, such as ngClick, so in most cases it is not necessary to use ngOn. However, AngularJS does not support all events and new events might be introduced in later DOM standards.

For more information, see AngularJS ng-on Directive API Reference.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.