AngularJS - Image "onload" event
Asked Answered
B

3

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.

Broaddus answered 9/7, 2013 at 12:14 Comment(0)
A
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.

Ambulant answered 6/11, 2014 at 14:28 Comment(2)
Thanks Sam, this works like a charm, I think I'll leave the sb prefix to give you credit.Mitran
Thumbs up for a scale-able solution that works well without jqLite (which was removed from Angular 2)Sulfite
B
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/

Broaddus answered 9/7, 2013 at 12:24 Comment(0)
E
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.

Ethelyn answered 30/3, 2019 at 14:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.