Bild geladenes Ereignis in für ng-src in AngularJS


106

Ich habe Bilder, die aussehen wie <img ng-src="dynamically inserted url"/>. Wenn ein einzelnes Bild geladen wird, muss ich die iScroll refresh () -Methode anwenden, damit das Bild scrollbar ist.

Was ist der beste Weg, um festzustellen, wann ein Bild vollständig geladen ist, um einen Rückruf auszuführen?


1
Schauen Sie sich $ http Response Interceptors an . Sie können dies verwenden, um einen Rückruf zu registrieren, wenn das Versprechen aufgelöst wird
Mark Meyer

Antworten:


185

Hier ist ein Beispiel für das Aufrufen von Image Onload http://jsfiddle.net/2CsfZ/2/

Die Grundidee besteht darin, eine Direktive zu erstellen und sie als Attribut zum img-Tag hinzuzufügen.

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 />

1
Was ist mit einem Fehlerrückruf?
Oleg Belousov

3
Was ist mit progressivem Image?
Nguyễn Đức Long

148

Ich habe dies ein wenig geändert, damit benutzerdefinierte $scopeMethoden aufgerufen werden können:

<img ng-src="{{src}}" imageonload="doThis()" />

Die Richtlinie:

.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);
                });
            }
        };
    })

Hoffe, jemand findet es sehr nützlich. Danke @mikach

Die doThis()Funktion wäre dann eine $ scope-Methode


3
Das ist richtig. Mikachs Lösung hat bei mir nicht funktioniert, bis ich wie Sie $ apply () verwendet habe.
Jeremy Thille

Dies ist die beste Antwort. Das JQUERY-Laden entfällt ebenfalls vollständig.
Noel Baron

Vielen Dank, dass Sie Semikolons gesetzt haben, damit Flusen nicht explodieren.
Richard


9

@ Oleg Tikhonov: Habe gerade den vorherigen Code aktualisiert .. @ mikach Danke ..)

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');
        });
    }
  };
});

1
Es könnte besser sein, dies in einer 'imageonerror'-Direktive zu haben, damit Sie eine andere Aktion ausführen können.
Jon Catmull

4

Gerade den vorherigen Code aktualisiert ..

<img ng-src="{{urlImg}}" imageonload="myOnLoadImagenFunction">

und Richtlinie ...

    .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);
                });
            }
        };
    })

4

Meine Antwort:

 var img = new Image();
 var imgUrl = "path_to_image.jpg";
 img.src = imgUrl;
 img.onload = function () {
      $scope.pic = img.src;
 }

genau das, wonach ich gesucht habe!
Zohab Ali

0

Im Grunde ist dies die Lösung, die ich letztendlich verwendet habe.

$ apply () sollte nur unter den richtigen Umständen von externen Quellen verwendet werden.

Anstatt Apply zu verwenden, habe ich die Bereichsaktualisierung auf das Ende des Aufrufstapels geworfen. Funktioniert so gut wie "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);
            });
        }
    };

}]);

Was meinst du mit " $apply()sollte nur von externen Quellen verwendet werden"? Ich folge nicht.
Echtfafa

@genuinefafa Was er unter "externen Quellen" versteht, ist nicht-eckiger Code. Wenn Sie beispielsweise einen generischen JS-Ereignis-Listener verwenden, um Code aufzurufen, der den Gültigkeitsbereich von $ ändert, müssen Sie dort $ apply verwenden. Wenn es sich jedoch um ein Angular-Ereignis oder eine $ scope-Funktion handelt, muss $ nicht angewendet werden, da der $ Digest-Zyklus bereits mit Angular-Methoden ausgeführt wird.
Tpartee
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.