Replace CSS background when image is loaded with AJAX
You can load your big image with javascript, and set the CSS background in the load event handler.
var img = new Image(); // Create new img element
img.addEventListener('load', function() {
// set background here
$('.MY-DIV-CLASS').css('background-image', 'url("bigImage.png")');
}, false);
img.src = 'bigImage.png'; // Set source path
Source: MDN Using_images
Additionally, here is a similar solution using jQuery How can I check if a background image is loaded?
How to show a placeholder image before the actual image loads in an Ionic 2 or 3 app
Can you modify your JSON to have a loaded
boolean property? If you can this will be easy, do as this:
<ion-card *ngFor="let item of items">
<img [src]="item.picture" (load)="item.loaded = true" [hidden]="!item.loaded" />
<img src="../path/to/your/placeholer/image.jpg" [hidden]="item.loaded">
</ion-card>
You'll have an loaded property always initalized as false
, when the image loads the (load)
event will be fired and change the image loaded property to true, hidding the placeholder image and showing the loaded imagem.
If you can't change this JSON (or if it's too big to edit) you can use the above code, but do the following in your page .ts
public functionWhoseIsLoadingYourJson(){
// HTTP REQUEST FOR JSON
.subscribe(response => {
response.forEach(element => {
element.loaded = false;
});
this.items = response;
});
}
Just iterate your response and in every object set a loaded property to false. If this throw some error you can put your <ion-card>
inside a div with a *ngIf
<div *ngIf="this.items != null">
<!-- ion card -->
</div>
EDIT - Updating JSON
Since it's coming from Firebase there's three options to update your JSON. The first one is a function whose you would execute just once to update your database, the second still is the code i gave (iterating through results and pushing the boolean value) but itll be different since you're using Firebase.
First solution:
Somewhere in your code, it can be any page, you just need to execute it once:
firebase.database().ref('myDataNode').on('value', snapshot => {
for(let key in snapshot.val()){
firebase.database().ref('myDataNode/' + key + '/loaded').set(false);
}
});
See that i'm looping through all resuts in your myDataNode
and using their key to set a loaded
property to false
. But take care when using set
since you can override all your nodes, before doing this method remember exporting your Firebase node to have a backup. And if you're pushing your images to Firebase from anywhere in your code remember to change it to set a loaded
property together.
The second one, as mentioned, is what i've done up in this answer, but now using it inside your Firebase call and using the forEach method that comes along with snapshot:
firebase.database().ref('myDataNode').on('value', snapshot => {
snapshot.forEach(element =>{
this.myDataNode.push({
picture: element.val(), // maybe it needs to be element.val().nameOfYourProperty
loaded: false
})
});
});
This'll push a new element to your array with the picture url and the loaded property. If it can't recognize the .push()
method just declare your variable typed as an array:
public myDataNode: any[];
The third one is just updating locally, itarate through your firebase snapshot, save the result in a local variable, create a new property and push it to your array:
firebase.database().ref('myDataNode').on('value', snapshot => {
for (let key in snapshot.val()){
snapshot.forEach(item => { // iterate snapshot
let record = item.val(); // save the snapshot item value in a local variable
record.loaded = true; // add the property
this.newArray.push(record); // push it to your array that'll be used in ng-for
return true; // return true to foreach
});
}
});
Hope this helps.
put a placeholder image until relevant image is loaded
Check out lazysizes or for the buzzword 'lazy loading'. It does exactly what you need I believe.
UPDATE
Check the demo, for example the section titled 'Image with LQIP technique'.
so basically your image tag should be now
<img src="placeholder-image.jpg" data-src="aws-image.jpg" class="lazyload" />
This image tag will display the placeholder image now. The library's javascript file will auto load the aws image once this image is scrolled into view and the aws file is loaded.
How to make a loading image while waiting for image to load in firefox
The problem is that your logic is operating on the same image element. Loading images are supposed to be separate from the image that's used to display stuff.
Here's code that loads a new image on the image element, and while that happens,we display the loading image somewhere until the other loads.
function showGalleryImage(path){
//get our placeholder
var theImage = document.getElementById('theimage');
//show our loading image. usually overlaying theImage
showLoadingImage(true);
//set our handler to check if loaded
theImage.onload = function(){
//when loaded, hide
showLoadingImage(false);
}
//start loading the new image
theImage.src = path;
}
function showLoadingImage(state){
//get our loading image placeholder
var loadingImage = document.getElementById('loadingImage');
//set our display states
var displayState = state ? 'block' : 'none';
loadingImage.style.display = displayState;
}
How to Lazy load the background image inside the inline style property (React)?
Here is a simple component to lazy load images:
class LazyBackground extends React.Component {
state = { src: null };
componentDidMount() {
const { src } = this.props;
const imageLoader = new Image();
imageLoader.src = src;
imageLoader.onload = () => {
this.setState({ src });
};
}
render() {
return <div {...this.props} style={{ backgroundImage: `url(${this.state.src || this.props.placeholder})` }} />;
}
}
You would call it with <LazyBackground src='path/to/hd.jpg' placeholder='path/to/placeholder.jpg' />
Loading CSS background images before normal images?
We need to assume things because you haven't shared your code.
Coming to your query, for now you can preload images using jQuery:
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
// Usage:
preload([
'img/imageName.jpg',
'img/anotherOne.jpg',
'img/blahblahblah.jpg'
]);
This saves the loading time of loading images.
How to Show an Local image till the NetworkImage() Loads Up in flutter?
You may want to try a FadeInImage
wrapped in a ClipOval
. FadeInImage
provides a placeholder
property you can use while the network image is loading.
Note: ClipOval
can be expensive if you do it a lot, so use it sparingly.
Related Topics
Inherited Text-Decoration Style
Bootstrap 4.1 - to Get Grid System Only
CSS Overlapping Elements & Opacity Issue
Webkit Linear Gradient Stops Render Incorrectly
How to Use Skew Only in the Parent Element
Concatenate String in Less in Loop
How to Overwrite CSS Variable with Its Own Value
Z-Index Between Children and Parents
Passing CSS Property:Value as SASS Mixin Argument
CSS Problem with Background-Attachment:Fixed;
Bottom-Border Hover Transition
Internet Explorer and Safari Mobile CSS Filter Invert
Improve CSS3 Text Rotation Quality
Svg Spritesheet Targeting with CSS