Having troubles preloading images with javascript - javascript

I'm trying to preload about 150 images and I want to be able to be able to do two things...
1) The images are being preloaded using a list of file names. Not every single file name in the list has a file to match up to it.
eg) pic04.jpg may not exist, even if it is in the list.
So when I'm preloading, i would like to be able to figure out whether or not the image exists, if possible.
2) Right now the function is simply preloading all 150 images using
pictures[i] = new Image();
pictures[i].src = "path/to/my/images/" + imageName[i] + ".jpg";
The function executes extremely fast, but the images don't seem to have been preloaded. Do I need to do something to make the site wait til the images have loaded before continuing?
Any ideas?

The function executes extremely fast, but the images don't seem to have been preloaded.
the images are being loaded asynchronously. The function finishes its execution but the browser continues loading the images in background
So when I'm preloading, i would like to be able to figure out whether or not the image exists, if possible.
yes, it is possible. You can use onerror event handler on the Image object
var img = new Image();
img.onerror=function(){alert('error: '+this.src);}
img.onload=function(){alert('image loaded: '+this.src);}
img.src='path/to/image.jpg';

Related

Fastest way to preload/load large images

Preload may not be the correct term...
I have a page which loads a very large image. I wanted to wait for the large image to completly load before displaying on the page for the user.
At the moment, I have a loading gif and i'm using javascript to wait for the image to load and then replace the loading gif src with the image:
<img src="loading.gif" id="image" />
<script>
img = 'very_large_image.jpg';
var newimg = new Image();
newimg.src = img;
newimg.onload = function(){
$('#image').attr('src',img);
}
</script>
I'm wondering if there are quicker ways to load this image such as a pure CSS way or some way to force the browser to download this asset first. The code above is obviously positioned in the location where the image is expected to load. So there is code above and below.
One CSS option I thought was to position the image off the screen and once it's loaded, perform the src replace.
My server is running http2, so it should be pretty quick. I just want to know if there is a better way then what i'm doing now to ensure the large image is loaded the quickest way possible for all major browsers.
I should add, i've already done plenty of optimisation of the image file already. I'm working with high resolution photography.
Thanks!
You can make the JPG progressive and then just let it load. Browsers will progressively display the image first blurry and then load more details.
This is the best way because user can see the image even before it's fully loaded.
Edit:
On linux use jpegtran, on Windows use Photoshop or RIOT
Your doing a great job!
Here is what I came up with:
https://jsfiddle.net/Vandeplas/jkwweh52/
HTML:
<img src="http://loadinggif.com/images/image-selection/32.gif" large-src="http://www.planwallpaper.com/static/images/518079-background-hd.jpg" large-class="fancyImg">
JS:
$('img[large-src]').each(function() {
var img = $(this);
var newimg = new Image();
newimg.src = img.attr('large-src');
newimg.setAttribute('class', img.attr('large-class'));
newimg.onload = function() {
img.replaceWith(newimg);
};
});
That separates the JS from the HTML + you can easily add infinite more pre-loading images without having to change the js!
Very easy way to preload images which are needed later
$.preloadImages = function() {
for (var i = 0; i < arguments.length; i++) {
$("<img />").attr("src", arguments[i]);
}
}
$.preloadImages("hoverimage1.jpg","hoverimage2.jpg");
I think that the best solution for your problem is split this image and load the parts assync at the same time

Change loading order of images already on page

Is there any way without AJAX of changing the loading order of images on a page? Or even a way to completely halt or pause loading of images already present?
The use case is simple - I have a long list of images down a page, and visitors will be landing on different spots of the page using URL anchors (/images#middle-of-page) that refer to actual containers for those images.
I'd like in the least to load the images inside the requested container FIRST, then continue loading the rest of the images.
The challenge is that there is no way to know the image paths of the requested container image before loading the page DOM.
I've tried getting the container img contents on load, then using the Javascript new Image() technique, but it doesn't change the fact that that image on the page will still be waiting for all previous images to load.
I've also tried immediately prepending a div in the body with a background image (CSS) of said img path, but this also does not prioritize the image load.
Any other ideas?
You need to have a DOM with empty img placeholders, i.e.
<img src="" mysrc="[real image url here]" />
Or you can make images to display "Loading..." image by default. You can even cache real image url in some custom tag, mysrc for example. Then once you know what exactly images you want to show (and in what order) you need to build a sequence of image loading
var images = [];//array of images to show from start and in proper order
function step(i){
var img = images[i++];
img.onload = function(){
step(i);
}
img.src = "[some url here]"
}
Hope this helps.
For interest, this is the function I ended up implementing based on the answers here (I made it an on-demand loading function for optimum speed):
function loadImage(img) { // NEED ALTERNATE METHOD FOR USERS w/o JAVASCRIPT! Otherwise, they won't see any images.
//var img = new Image(); // Use only if constructing new <img> element
var src = img.attr('alt'); // Find stored img path in 'alt' element
if(src != 'loaded') {
img
.load(function() {
$(this).css('visibility','visible').hide().fadeIn(200); // Hide image until loaded, then fade in
$(this).parents('div:first').css('background','none'); // Remove background ajax spinner
$(this).attr('alt', 'loaded'); // Skip this function next time
// alert('Done loading!');
})
.error(function() {
alert("Couldn't load image! Please contact an administrator.");
$(this).parents('div:first').find("a").prepend("<p>We couldn't find the image, but you can try clicking here to view the image(s).</p>");
$(this).parents('div:first').css('background','none');
})
.attr('src', src);
}
}
The img loading="lazy" attribute now provides a great way to implement this.
With it, images load automatically only when on the viewport. But you can also force them to load by setting in the JavaScript:
document.getElementById('myimg').loading = 'eager';
I have provided a full runnable example at: How do you make images load lazily only when they are in the viewport?
One really cool thing about this method is that it is fully SEO friendly, since the src= attribute contains the image source as usual, see also: Lazy image loading with semantic markup

How to load an image asynchronously?

I'm loading an image onto a texture map with GLGE (sorta like webGl). However for the sake of loading speed I'm loading a low resolution image first (which would be quicker) and then want to change the src to the high resolution image once the large image is loaded. This is what I'm doing now
var texture = new GLGE.texture();
function updateTexture(){
var image=new Image();
image.src = "models/testLargeMap_map0.jpg"; // load image
image.onload = function(){
texture.image("models/testLargeMap_map0.jpg"); // supposedly swap image on load (not working as I thought)
}
}
However, when during this period of changing the src, the model and all its functions freeze. How do I make it load the image asynchronously and on load swap it to the higher texture for a smooth instantaneous texture change?
You can set an image.onload event handler like this:
var big_image = new Image();
big_image.onload = function () {
texture.image("models/testLargeMap_map0.jpg");
}
big_image.src = "models/testLargeMap_map0.jpg";
(Note that I set the onload handler first, then set the src attribute. If I do it the other way around, it fails in IE).
This will preload the image before calling texture.image. I don't know anything about this library though, so I can't be certain it will use the pre-loaded image.
The image.src will be requesting the image from the server and it will initiate the onload event, and again u are requesting the image to be swapped so it is getting freezed. Why do you need this approach. You can have better way of doing this like, allow the low resolution image to be loaded first then assign the onmouseover or onclick event for the image on that time u can show a popup like shown on google images and then in it just display the high resolution images. On that time u will be requesting a single image the process will be quicker.
Hope this helps you
I'm not familiar with "GLGE" but it looks like the problem is that the method .image() loads the image again (kind regardless if that happens in the load event handler for the same image).
So unless you can set the image reference directly, like
texture = this; // within the load handler
there is no way to accomplish it with this library.

Detect if objects are loaded [Javascript]

I was wondering, is there a way to detect if a certain image / div is loaded?
For example when i am loading two heavy images and showing a loading sign at the two places the images will later occupy, is there a way to already display the first image when it's loaded while still loading the second one?
myImage.addEventListener('load', function() { ... }, false);
Code inside the above function will be called when the image is finished loading.
If you are using new Image to preload images, then you can do the following to be notified of then it is loaded
var img = new Image();
img.onload = function() {
//display the image
document.getElementById("myDiv").innerHTML = "%3Cimg src='myimg.jpg' alt=''/%3E";
};
img.src = "myimg.jpg";
Remember to set the src after the onload.
if an image is done loading, its .complete property switches to true.

Changing <img src="XXX" />, js event when new image has finished loading?

I have a photo gallery web page where a single <img src="XXX" /> element's src is changed (on a click) with JavaScript to show the next image—a poor man's ajax I guess. Works great on faster connections when the new image appears almost immediately. Even if it takes a few seconds to load, every browser I've tested it on keeps the old image in place until the new one is completely loaded.
It's a little confusing waiting those few seconds on a slow connection, though, and I'm wondering if there's some JavaScript event that fires when the new image is done loading, allowing me to put a little working... animated gif or something up in the meantime.
I know I could use AJAX for real (I'm using jQuery already), but this is such a nice and simple solution. Besides this lag, is there any other reason I should stay away from this approach to changing images?
You can set up a handler on the "load" event.
$('img.whatever')
.load(function() { /* do stuff */ })
.attr('src', newURL);
Actually I guess you'd want to do this with "live()":
$('img.reloadable').live('load', function() { $(this).show(); });
// ...
$('img#someId').hide().attr('src', newURL);
edit — whoa, where did that year go? Well, it turns out that one problem with that "live" approach I typed in way back when is that the "load" event does not bubble. Now what you can do, however, is leverage the way that "Image" objects (as opposed to <img> DOM elements) behave. Basically, the function that changes the URL can use an "Image" element as the place to keep the handler. The code that changes the actual "src" attribute of the real <img> tag would then also update the "src" of the "Image" object instance. The browser will only really load the image once (assuming cache control is all cool), but the browser will still call the "onload" handler of the "Image":
(function() {
var imageObj = new Image();
imageObj.onload = function() {
// code to run when image loads from server
};
$('#hypotheticalButton').click(function() {
$('#imgToUpdate').attr('src', newURL);
imageObj.src = newURL;
});
})();
You just just preload the images with jQuery so that way when the user clicks, the next image is already loaded and there shouldn't be a delay...that is unless the user goes to your page, and starts clicking on the image before they are loaded.
http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript
var slideimg = $('#slideimage');
slideimg.click(function(){
var img = new Image();
var url = 'url_to_next_image.jpg';
$(img).bind('load',function(){
$('#loading').hide();
slideimg.attr('src',url);
}).attr('src',url);
$('#loading').show();
});
This should work even with IE's crazy cache handling.

Categories