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?

Sergei Basharov
quelle
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 />
mikach
quelle
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

Peter
quelle
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
Dies gibt mir diesen Fehler: code.angularjs.org/1.4.9/docs/error/$rootScope/…
Paulo Roberto Rosa
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');
        });
    }
  };
});
Kailash
quelle
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);
                });
            }
        };
    })
Ramiro Spanien
quelle
4

Meine Antwort:

 var img = new Image();
 var imgUrl = "path_to_image.jpg";
 img.src = imgUrl;
 img.onload = function () {
      $scope.pic = img.src;
 }
Rodrigo Andrade
quelle
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);
            });
        }
    };

}]);
Doug
quelle
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