AngularJS - Image "onload" event

58,915

Solution 1

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.

Solution 2

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/

Solution 3

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.

Share:
58,915
Ivan Chernykh
Author by

Ivan Chernykh

JavaScript/ReactNative/React, Firebase/Google Cloud. Also Express/Node, Expo, Ruby on Rails, CI/CD, PHP, Angular/Ionic, HTML5/CSS3, AS3/Starling/Box2D, XML/XSL/XSD, Webpack, Git, Grunt, Gulp, Sass, Cordova, PhoneGap, jQuery, Unix/ShellJS. Still love Macromedia Flash! CTO at https://tryriplewhale.com Creator of "Rock Paper Scissors Puzzle":

Updated on April 01, 2020

Comments

  • Ivan Chernykh
    Ivan Chernykh about 4 years

    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.

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