javascript/jquery start loading hidden images when page is ready - javascript

I have a bunch of images on a website that have two versions: a large one and a small one.
The small version automatically display when you visit the website and when you click them, I use jquery to open up a hidden div and insert the large version.
Since the large images are not visible to the browser when the page loads (no img has them as a src), they will not be loaded until the user clicks one of the small images to enlarge it, and therefore they will not slow down page loading time.
To make the UI as responsive as possible however, I would like to start buffering the large images from the moment the page has loaded (so that they are there when the user clicks one of them).
how can I start loading images in the background?

You can start loading images in the background when you set a src to an Image object, f.ex:
(new Image).src = src;
Here is a function for you:
function preloadImages() {
for(var i=0; i<arguments.length; i++) {
(new Image).src = arguments[i];
}
}
preloadImages('one.jpg', 'two.jpg');
I suggest you start preloading the images when the window has loaded (inside the window.onload callback) to prevent it from sabotaging the UI:
window.onload = function() {
preloadImages('one.jpg', 'two.jpg');
};

Related

web img tag load image block scrollbar and the main thread. How to resolve for UX

I have a list of products when enter this page. Will get a list of product and product image, this image is larget, but request time is not a problem. And I will set this image like Thumbnail, then the problem happened when a list of image loading on img tag, the scrollbar will be blocked.
The problems:
image have been load(not Http request) and append image to DOM will block the main thread?
How to solve this problem besides Compresse the picture at the backend?
Depending on how much prioritiy you want to give images you could do something like load the html tag with:
<img data-unloaded_src="[your image location]" scr="">
Then load the image later on with something like
window.requestIdleCallback(function(){
var all_images = document.getElementsByTagName('img');
for(var i = 0; i < all_images.length; i++){
if(all_images[i].dataset.unloaded_src){
all_images[i].src = all_images[i].dataset.unloaded_src;
}
}
});
Your milage will vary using requestIdleCallback. You might want to just trigger it on dom content loaded or something? It seems odd that any image loading would lock up the scroll bar...

How to preload image offscreen and then move to different onscreen element?

I'm building a website/app that will display six different images at a time. The contents of those images are loaded from another site and changing regularly. Where any particular image goes on screen depends on the state of all images already on screen.
To get the image I use jQuery to change the src attribute of one of the 6 img locations, then wait for the load using jQuery load(), then show it. However, this means I have to pick my location before the image is loaded. The problem I'm having is that between the time I initiate the load and when the image finally does load, the proper location for that image might have changed.
So my question is whether there's a way to load the image offscreen (say in a hidden img), and then, when it's loaded, get a notification of it being finished and then move that image to the correct location at that moment.
I've found lots of preload questions and answers on StackOverflow, but they all presume you know where you want the image to go when you initiate the load.
Update: thinking more on this question, perhaps another way of framing it is 1) if I load an image from an offsite server into an offscreen/hidden img and wait for it to load, 2) would subsequently setting the src attribute of an onscreen/visible img to the same image URL draw from the server or the browser cache? In other words, if I load a remote image offscreen does the next request for that same image go back to the server or to the browser cache (and would this be consistent for all browsers)?
One Way to do it:
function loadImg(url, callback, key) {
var image = new Image();
image.onload = function() {
callback(image, key)
};
image.onerror = function() {};
image.src = url;
}
function imageOnload(image, key) {
imageGoesTo[key].src = image.src
}
var imageGoesTo = {
"firstPicture": document.getElementById("img1"),
"secondPicture": document.getElementById("img2"),
}
loadImg("http://7pi.azurewebsites.net/img/DSC09906.jpg", imageOnload, "firstPicture")
imageGoesTo["secondPicture"] = document.getElementById("img3")
loadImg("http://7pi.azurewebsites.net/img/DSC07934.jpg", imageOnload, "secondPicture")
<img id="img1" alt="loading">
<img id="img2" alt="loading">
<img id="img3" alt="loading">

Print popup in JavaScript missing images

I want to open a new window/tab, put some HTML in the document, then bring up the browser print dialog to print that new window. I am using the following to accomplish this:
var w = window.open();
w.document.write(html);
w.document.close();
Where html contains:
...<body onload="window.print()">...</body>...
This all works, the window pops up, and the print dialog is shown for the new page, however, for some reason the browser isn't waiting for all the images on the page to load before showing the print dialog. It's causing some images not to print.
There are many images, and they are dynamically generated on the server side (takes about 1 sec each to load). How do I force the browser to only print once all the images are loaded?
This happens in Chrome and Firefox that I've confirmed. I appreciate any help.
Try putting your printer call in an onload event for the last image.
<img onload="window.print()" ... />
EDIT:
Full answer by OP as seen below:
I came up with the following script using #chockleyc's answer as inspiration. I couldn't just use the last image because they don't necessarily load in order. The following script will print the page after all images have loaded (uses jQuery):
var hasPrinted = false;
$(document).ready(function(){
$('img').load(function(){
var imgs = $('img');
var loadedAll=true;
for(var i=0;i<imgs.length;i++){
loadedAll &= $(imgs[i])[0].complete;
}
if (loadedAll && !hasPrinted) {
console.log('printing');
hasPrinted = true;
window.print();
}
else {
console.log('not all images have loaded');
}
})
});
Try changing it from the body.onload event to the window.onload event.
w.window.onload = window.print()
Or something like that.

How to detect if the browser is loading

I am trying to show a loading image when a users click a link that will show a large image in the same page.
I was wondering what's best way to detect image loading WHILE the page has been loaded already (so window.onload() doesn't work).
Load the image with JavaScript and then you can use the image's onLoad attribute:
Image1 = new Image();
Image1.src = 'photo.gif';
/* Code here to display loading hour glass etc */
Image1.onload = function() {
/* Image has loaded here */
}
$("img.loader").show();
$("img.big").ready(function() {
$("img.loader").hide();
}):
Add "onclick" event to your link, in which via setTimeout show your loading image. E.g.
Link Text
function showLoading() {
// Code to show "Loading..."
}

How to detect progress loaded for GroundOverlay

I am loading 10 GroundOverlays onto a GoogleMap and would like to show the progress associated with loading the images.
var imageBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(42.80059,-115.253806),
new google.maps.LatLng(47.481725,-110.227471));
var layer1 = new google.maps.GroundOverlay("overlays/layer1.png",imageBounds);
layer1.setOpacity(.5);
layer1.setMap(map);
How can I detect when the actual image of each overlay has loaded or the % loaded? I'd like to add a progress bar or something to show the user that overlays are loading as it can take 5 seconds or so.
If you have one single image as a groundoverlay, I'd do the following:
Create an img tag through javascript
Set its src to overlays/layer1.png
display a waiting box
Add an onload event to it, on which load it as a gmaps overlay and close the waiting box.
Progress... that's a bit more browser specific. But loading is easy, so:
function loadOverlay(){
var img = new Image();
var img_url = "overlays/layer1.png"
img.src= img_url;
$('#wait_for_overlay').show();
img.onLoad = function(){
$('#wait_for_overlay').hide();
var layer1 = new google.maps.GroundOverlay(img_url,imageBounds);
layer1.setOpacity(.5);
layer1.setMap(map);
}
};
Reason why this will work:
Creating an img object and setting its 'src' attribute will make the browser start to download the requested file as soon as the javascript function doing this has finished.
The browser will put this image into its local cache, then call the onLoad function to see what should happen with it.
The callback actually does nothing to the img variable (perhaps it should, make sure it doesn't get wiped out as per closure rules, do a NOP with it if this is buggy), but instead calls the google-maps function.
The google-maps function will request the image at the exact same url, at which the browser will look up its cache table, and bring the image back immediately from cache.
This trick is nasty, but in fact, the google maps engine will do the exact same onLoad thingy in the background (as this is how map engines work).
I hope this satisfies your question... no progress bar, just a loading indicator... Perhaps you could do progress bar by requesting it with XHR and checking progress, I'm not sure, but the trick will be the same: do a faux request, in order to make it arrive to the cache.
I doubt you can do it. You may request for new functions added to the GroundOverlay class in order for the users to have more access and control over the loaded image. I'd like to have those kind of functions for my projects too.
As of 10 years later, 2021 Dec. I can confirm that #Aadaam 's idea works great !
Try my example:
click the example link, try zoom map or pan,
it load image as groundOverlay, the progressing bar show on left panel bottom.
new Image()
is HTML img object, document is here
img_object.onload
is all lowercase, if you write
.onLoad
will give you error.
https://transparentgov.net:3200/googlemaps12/default?layer_id=0&layer=SilverRock_MasterPlan_29Nov2016_s200-images.jpg&center_lat=33.65789936781538&center_long=-116.25862990762825&center_zoom=15&url=https%3A%2F%2Fgis.la-quinta.org%2Farcgis%2Frest%2Fservices%2FCommunity_and_economic%2FSilver_Rock_Master_Plan%2FMapServer&panto=0&overlayOpacity=8&overlayType=overlayType_image

Categories