2016-01-26 16 views
12

Ho il seguente ng-repeat che acquisisce i dati da una chiamata $http.post e li memorizza in $scope.data.Angularjs attendi fino a div immagine-sfondo di sfondo mostra

<div ng-repeat="key in [] | range:data.pages"> 
    <div class="pageBackground" id="page_{{ (key+1) }}" ng-style="{'background-image':'url(/images/{{data.id}}/{{(key+1)}}.png)'}"> 
    <!-- some random stuff here --> 
</div> 

cosa normale che accade è la classe .pageBackground verrà caricato prima che l'immagine di sfondo fa sullo schermo. Mi piacerebbe che non si presentasse nulla fino a quando lo background-image non è stato caricato, ma non sono stato in grado di capirlo.

Qualcuno ha qualche suggerimento?

+0

Hai provato questo approccio? [Il modo più semplice per ritardare il caricamento di immagini in Agular @ StackOverflow] (http://stackoverflow.com/questions/20229606/questo-è-il-sempre-modello-delay-carico-load-di-immagini-in-angolare) – SL8t7

+0

Puoi creare un plnkr che riproduce questo problema? Mi sembra che la risposta di @ sp00m dovrebbe funzionare. –

risposta

0

È possibile ritardare la funzione di avvio fino al caricamento dell'immagine.

var img = new Image(); 
    img.onload = function(){ 
    loadData(); 
    }; 
    img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg'; 

Poi pose ng-if="imageLoaded" in html e set che true nella funzione loadData.

+0

La quantità di pagine/immagini non viene mai definita e le immagini provengono sempre da una fonte diversa. Questo metodo sembra un po 'noioso per il mio esempio, ma grazie per la raccomandazione. – bryan

5

Non sono sicuro che esista una soluzione reale per il tuo problema. Una soluzione alternativa potrebbe essere l'uso dell'oggetto Image, come spiegato in this answer. Per esempio come una direttiva:

angular.module("yourModule").directive("showOnceBackgroundLoaded", [function() { 
    return { 
    restrict: "A", 
    scope: false, 
    link: function (scope, element, attributes) { 
     element.addClass("ng-hide"); 
     var image = new Image(); 
     image.onload = function() { 
     // the image must have been cached by the browser, so it should load quickly 
     scope.$apply(function() { 
      element.css({ backgroundImage: 'url("' + attributes.showOnceBackgroundLoaded + '")' }); 
      element.removeClass("ng-hide"); 
     }); 
     }; 
     image.src = attributes.showOnceBackgroundLoaded; 
    } 
    }; 
}]); 

Usa:

<div ng-repeat="key in [] | range:data.pages"> 
    <div class="pageBackground" id="page_{{ (key+1) }}" show-once-background-loaded="/images/{{data.id}}/{{(key+1)}}.png"> 
    <!-- some random stuff here --> 
</div> 
+0

Grazie per l'aiuto, ma questo non sembra funzionare. Una volta che il div appare nuovamente, l'immagine di sfondo è ancora in ritardo nell'apparire – bryan

0

Ecco una direttiva che incorpora la vostra immagine come sfondo, e attende di manifestarsi fino a quando dopo che l'immagine è stata caricata. È possibile includere variabili all'interno del parametro "mysrc" come necessario per generare immagini diverse (ad esempio all'interno di una ng-repeat).

angular.module('foo', []) 
 
    .directive('myPageBackground', function() { 
 
    return { 
 
     scope: { 
 
     key: '=', // used for ID of the element; if you set the ID externally to the directive you could omit this 
 
     mysrc: '=' // used for the URL of the desired background image 
 
     }, 
 
     template: '<div ng-show="showMe" class="pageBackground" id="page_{{key}}" ng-style="{\'background-image\':\'url({{mysrc}})\'}"></div>', 
 
     link: function(scope) { 
 
     var img = new Image(); 
 
     img.onload = function() { 
 
      scope.showMe = true; 
 
      scope.$apply(); 
 
     }; 
 
     img.src = scope.mysrc; 
 
     } 
 
    } 
 
    });
.pageBackground { 
 
    width: 200px; height: 200px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="foo"> 
 
    <!-- Done with hardcoded values here, just for demo: --> 
 
    <div my-page-background key="'1'" mysrc="'http://placehold.it/200x200'"></div> 
 
    <div my-page-background key="'2'" mysrc="'http://placehold.it/150x150'"></div> 
 
    <div my-page-background key="'3'" mysrc="'http://placehold.it/100x100'"></div> 
 
</div>

0

Se si sta utilizzando sempre lo stesso class="pageBackground", allora l'immagine di sfondo è sempre lo stesso. È possibile caricare nella immagine nascosta, quindi il browser memorizza nella cache:

<img src="url" style="display:none;"/> 

O precaricare con javascript nella pagina di carico:

var img = new Image(); 
img.src = 'some url'; 

Credo che post è attivato con l'interazione dell'utente, che avviene sicuramente dopo che la pagina è stata caricata, quindi l'immagine si trova già nel browser e apparirà immediatamente quando si applica class="pageBackground"

Spero che questo aiuti!

+0

La classe è sempre la stessa, ma se si guarda il mio codice, l'attributo 'background-image' cambia con' ng-style' – bryan

+0

@bryan sorry, mi sono perso, mio ​​male! –

0

È possibile utilizzare la direttiva ngSrc anziché un div. Inoltre, è possibile provare a utilizzare una piccola libreria di immagini con caricamento lazy come ng-lazy-img.

Spero che questo aiuti!

0

Ecco un esempio completamente funzionante che utilizza l'oggetto Immagine.

function AppCtrl($scope) { 
 
    $scope.images = [{ 
 
    src: 'https://farm4.staticflickr.com/3261/2801924702_ffbdeda927_d.jpg' 
 
    }, { 
 
    src: 'https://farm9.staticflickr.com/8455/8048926748_1bc624e5c9_d.jpg' 
 
    }]; 
 
    angular.forEach($scope.images, function(image) { 
 
    var img = new Image(); 
 
    img.onload = function() { 
 
     $scope.$apply(function() { 
 
     image.loadedSrc = image.src; 
 
     }); 
 
    }; 
 
    img.src = image.src; 
 
    }); 
 
}
.hasSrc { 
 
    color: purple; 
 
    padding: 10px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app> 
 
    <div ng-controller="AppCtrl"> 
 
    <div ng-repeat="image in images" ng-class="{ hasSrc: !!image.loadedSrc }" style="background-image: url({{image.loadedSrc}})"> 
 
     <h2>THIS IS SOME TEXT BEING USED</h2> 
 
     <p> 
 
     This text is being used for illustration purposes only. 
 
     </p> 
 
    </div> 
 
    </div> 
 
</div>

Dovrebbe essere abbastanza facile da adattare questo per soddisfare i vostri scopi.

1

Guardate qui per una soluzione:

How can I tell when a CSS background image has loaded? Is an event fired?

quello che fai è di creare un elemento socio invisibile caricare la stessa immagine. se e solo se quell'immagine è stata caricata (evento onload) mostri il tuo altro elemento, ad esempio:

<div ng-repeat="key in [] | range:data.pages" ng-init="_imageLoaded={}"> 
    <div ng-show="_imageLoaded[$index]" class="pageBackground" id="page_{{ (key+1) }}" ng-style="{'background-image':'url(/images/{{data.id}}/{{(key+1)}}.png)'}"> 
    <img ng-show="false" src="/images/{{data.id}}/{{(key+1)}}.png" onload="_imageLoaded[$index] = true;" /> 
    <!-- some random stuff here --> 
</div> 
+0

Ehi, Patrick, grazie per la risposta. Non sono sicuro di cosa '_imageLoaded = {}' provenga. Ad ogni modo puoi dare più contesto. Quelle domande non mi aiutano troppo: \ – bryan

+0

hey, io uso l'oggetto imageLoaded per ricordare ogni voce se l'immagine corrispondente è stata caricata. quindi _imageLoaded.0 sarà indefinito in primo luogo - ma quando l'immagine con $ index = 0 viene caricata, metterà la voce su true - ciò accade nella funzione onload. il tuo div sull'altro lato ha un ng-show "in ascolto" di questa variabile. quindi quando passa da indefinito a vero verrà visualizzato div. che è quando l'immagine è caricata, quindi cosa stavi chiedendo. il _imageLoaded è solo un modo per implementarlo –

Problemi correlati