Angularのng-srcは、画像を内部的にプリロードするまで前のモデルを保持します。私は各ページのバナーに異なる画像を使用しています。ルートを切り替えるとき、メインビューを変更し、ヘッダービューをそのままにして、持っているときにbannerUrlモデルを変更します。
これにより、新しいバナーの読み込み中に以前のバナー画像が表示されます。
まだ指令がないのには驚いたが、構築する前に議論をしたかった。
私がやりたいことは、カスタム属性にバナーモデルがあることです。のような:
<img preload-src="{{bannerUrl}}" ng-src="{{preloadedUrl}}">
次に、bannerUrlの変更用の$ scope.watchを変更し、変更したらすぐにng-srcをローダースピナーに置き換え、次に一時的なimg dom要素を作成し、preload-srcからイメージをプリロードしてから、preloadUrlにアサートします。
たとえば、ギャラリーでも複数の画像を処理する方法を考える必要があります。
誰もが何か入力をしていますか?または誰かが私に既存のコードを指すことができますか?
Background-imageを使用するgithubで既存のコードを見てきましたが、アプリが応答するため動的な高さ/幅が必要であり、background-imageでそれを行うことができないため、私には機能しません。
ありがとうございました
ディレクティブに2つのURLがあると、タッチが複雑になりすぎます。私がより良いと思うのは、次のように機能するディレクティブを書くことです:
<img ng-src="{{bannerUrl}}" spinner-on-load />
また、ディレクティブはng-src
を監視し、(たとえば)画像が読み込まれるまでスピナーでvisibility:falseを設定できます。のようなもの:
scope: {
ngSrc: '='
},
link: function(scope, element) {
element.on('load', function() {
// Set visibility: true + remove spinner overlay
});
scope.$watch('ngSrc', function() {
// Set visibility: false + inject temporary spinner overlay
});
}
このように、要素はng-src
属性を持つ標準のimgと非常によく似た振る舞いをします。
誰かが興味を持っているなら、これが私の最終的な解決策です。Twitterブートストラップを使用します。そのため、すべての画像に「フェード」クラスを追加し、画像が読み込まれたときにフェードインおよびフェードアウトするディレクティブでクラス「in」を切り替えるだけです
angular.module('myApp').directive('imgPreload', ['$rootScope', function($rootScope) {
return {
restrict: 'A',
scope: {
ngSrc: '@'
},
link: function(scope, element, attrs) {
element.on('load', function() {
element.addClass('in');
}).on('error', function() {
//
});
scope.$watch('ngSrc', function(newVal) {
element.removeClass('in');
});
}
};
}]);
<img img-preload class="fade" ng-src="{{imgSrc}}">
作業例: http://ishq.org
必要に応じて、ディレクティブの属性として画像の失敗と画像ローダーを渡すことができます。
myApp.directive("mySrc", function() {
return {
link: function(scope, element, attrs) {
var img, loadImage;
var IMAGE_LOAD="123.jpg";
var IMAGE_FAIL="123.jpg";
img = null;
loadImage = function() {
element[0].src = IMAGE_LOAD;
img = new Image();
img.src = attrs.mySrc;
img.onload = function() {
element[0].src = attrs.mySrc;
};
img.onerror=function ()
{
element[0].src = IMAGE_FAIL;
}
};
loadImage();
}
};
});
ディレクティブが実際にスピナーを作成し、自動的に削除するため、これはおそらく最もエレガントなソリューションだと思います:
app.directive('spinnerLoad', [function spinnerLoad() {
return {
restrict: 'A',
link: function spinnerLoadLink(scope, elem, attrs) {
scope.$watch('ngSrc', function watchNgSrc() {
elem.hide();
elem.after('<i class="fa fa-spinner fa-lg fa-spin"></i>'); // add spinner
});
elem.on('load', function onLoad() {
elem.show();
elem.next('i.fa-spinner').remove(); // remove spinner
});
}
};
}]);
Htmlは次のとおりです。
<img ng-src='{{imgUrl}}' spinner-load />
注:ここで説明されているように動作させるには、font-awesomeを使用する必要があります
代わりに
element.on('load', function() {});
imagesLoaded プラグインを使用します。画像を劇的に高速化します。
したがって、最終的なコードは次のようになります。
link: function(scope, element) {
imagesLoaded(element, function() {
});
scope.$watch('ngSrc', function() {
});
}
共有するだけ^^
//css
.media-box{
position: relative;
width:220px;
height: 220px;
overflow: hidden;
}
.media-box div{
position: absolute;
left: 0;
top: 0;
}
.spinner{
position: absolute;
left: 0;
top: 0;
background: #CCC url(./spinner.gif) no-repeat center center;
display: block;
width:220px;
height: 220px;
}
.feed img.spinner-show{
visibility: visible;
}
.feed img.spinner-hide{
visibility: hidden;
}
//html
<div class="media-box">
<div>
<img data-ng-src="{{item.media}}" alt="" title="" data-spinner-on-load>
</div>
</div>
//js
.directive('spinnerOnLoad', function() {
return {
restrict: 'A',
link: function(scope,element){
element.on('load', function() {
element.removeClass('spinner-hide');
element.addClass('spinner-show');
element.parent().find('span').remove();
});
scope.$watch('ngSrc', function() {
element.addClass('spinner-hide');
element.parent().append('<span class="spinner"></span>');
});
}
}
});
Img-srcが変更されたときにスピナーを表示するこのディレクティブがあります:
<img-with-loading
img-src="{{src}}"
spinner-class="{{spinnerClass}}"
/>
ルート変更時に image-preloader factoryを使用してイメージをプリロードし、解決することができます:
// call REST
return getContent.get().$promise.then(function(response) {
//return response;
// preload images from response
var imageLocations = [
// put image(s) from response to array
response.PostImage.big[0],
];
// check do we have (all) image(s) in array
console.log(imageLocations);
// return when all images are preloaded
return preloader.preloadImages( imageLocations )
.then(function() {
//if it was success
return response;
},
function() {
//if it failed
return response;
});
});
ここでチュートリアルを完了してください: https://www.coditty.com/code/angular-preload-images-on-route-change-by-using-resolve