Preloading images in an array (and waiting until they have downloaded) - javascript

So I came across another problem.
When I started redoing the webpage I am working on , I came across an idea - Why not have the page preload the materials, and while it's doing just that, show a loading screen?
Well, I made a function for that, but the thing is, it starts doing what it's supposed to, until it comes to the open() part of the image preloading. It simply does not work. It is because I am giving it the arguments[i] part that is causing it to stop there? Is there a better way to do it?
function mainPageLoad() {
var loadScreen = document.getElementById('pageload');
loadScreen.innerHTML = "<p>Loading<span id='loadingWhat'>...</span></p><img src='images/loading.gif?v2'>";
var loadspan = document.getElementById('loadingWhat');
loadspan.innerHTML = " images";
preloadImages(["images/logo.jpg"])
//loadspan.innerHTML = " content";
//preloadContent([""]);
}
function preloadImages() {
var images = new Array();
var imagesToLoad = arguments.length;
document.writeln(imagesToLoad);
var imagesLoaded = 0;
document.writeln(imagesLoaded);
for (i = 0; i < arguments.length; i++) {
document.writeln("Loading images.");
images[i] = new XMLHttpRequest();
document.writeln("Made object");
images[i].open("GET", arguments[i], true);
document.writeln("Well, that worked.");
images[i].send(null);
document.writeln("Sent.");
images[i].onreadystatechange = function() {
document.writeln("Ready state change!");
if (images[i].readystate == 4 && images[i].status == 200){
imagesLoaded = imagesLoaded + 1;
window.alertln("We have loaded another image.");
window.alertln("Image" + String(imagesLoaded) + "out of" + String(imagesToLoad));
}
}
}
}
window.onload = init;

Here's a much, much simpler way to preload images and have it call a callback when the images are done loading in a related prior question/answer: Image preloader javascript that supports events.

Related

Preloaded images are not beeing used

I am trying to preload images for use in a image gallery. The images are taken threw a php script from a folder outside of the htdocs folder. And when they are loaded the images should be used in a masonry layout.
As far as my knowledge goes the javascript that I am using should be working. However when I am using the page on a gallery for several 100 images it does not work. Some images are loaded others are not.
I also have very little knowledge of javascript in general. So any advice would be helpful.
I tried a lot of things. The imagesloaded from desandro. Several iterations of the script I will share on the bottom. I am at a loss.
Javascript code
<script type="text/javascript">
var images = <?php echo json_encode($images); ?>;
var folder = <?php echo json_encode($folderName); ?>;
var imageArray = [];
function preloadImages() {
for (var i = 0; i < images.length; i++) {
var img[i] = new Image();
img[i].src = "img/jpg/" + folder + "/" + images[i].image_name;;
imageArray.push(img);
}
}
</script>
JSON example (for the images)
{"image_id":"8","image_name":"DSC00058.JPG","image_selected":"1","image_locked":"0"},
{"image_id":"9","image_name":"DSC00053.JPG","image_selected":"1","image_locked":"1"},
HTML
<body class="h-100 bg-light" onload="preloadImages();">
The expected result would be that the masonry only starts building and using the images that are preloaded. Is there a way to use the preloaded images or do I need to doe a specific thing in HTML?
Your preload function is loading the images, but it's not preloading them. The trick is to wait for them all to load before initializing the masonry plugin..
Here's an example using promises.
function preloadImages() {
var promises = [];
for (var i = 0; i < images.length; i++) {
promises.push(new Promise(done => {
var img[i] = new Image();
img.onload = ()=>done();
img[i].src = "img/jpg/" + folder + "/" + images[i].image_name;;
imageArray.push(img);
}));
}
Promise.all(promises).then(()=>{
// initialize masonry here...
});
}

javascript slideshow links on the same page

I just copied JavaScript code from Google, and I don't know how to make a hyperlink that will be opened on the current page.
Here's the code which I inserted into the <head> section of my page.
var slideimages = new Array()
var slidelinks = new Array()
function slideshowimages() {
for (i = 0; i < slideshowimages.arguments.length; i++) {
slideimages[i] = new Image()
slideimages[i].src = slideshowimages.arguments[i]
}
}
function slideshowlinks() {
for (i = 0; i < slideshowlinks.arguments.length; i++)
slidelinks[i] = slideshowlinks.arguments[i]
}
function gotoshow() {
if (!window.winslide || winslide.closed) winslide = window.open(slidelinks[whichlink])
else winslide.location = slidelinks[whichlink]
winslide.focus()
}
Here's the code I inserted into the body section:
<script>
<!--
slideshowimages("main.PNG", "mainhover.PNG")
slideshowlinks('index.php', '_self')
//configure the speed of the slideshow, in miliseconds
var slideshowspeed = 2500
var whichlink = 0
var whichimage = 0
function slideit() {
if (!document.images) return
document.images.slide.src = slideimages[whichimage].src
whichlink = whichimage
if (whichimage < slideimages.length - 1) whichimage++
else whichimage = 0
setTimeout("slideit()", slideshowspeed)
}
slideit()
slideit()
//-->
</script>
Everytime I click on the image, the index.php page always appears on the new tab,
is there an easy way, so that the index.php page can be opened on the same page?
I know nothing about JavaScript.
Seeing the HTML will help understand the issue, but this code
if (!window.winslide || winslide.closed) winslide = window.open(slidelinks[whichlink])
else winslide.location = slidelinks[whichlink]
winslide.focus()
basically tells that if this is the first time you run it, then open a new window (window.open(slidelinks[whichlink]) which Chrome for example will use to open a new tab
Else if it's already created, change that window's location to the slide URL (else winslide.location = slidelinks[whichlink] e.g it's as designed to operate in a new window
to change it, you'll need to replace window.open with something that will operate on an iframe or something.
I'm not sure what is the purpose of opening a new window, but this is what the code does
On a side note, I'm not sure you found the best piece of code to run HTML based slides, If you want modern slides, I would try something like http://lab.hakim.se/reveal-js/

Precache a varying number of images in jQuery and call back if all are loaded

I would like to do an animation with the images, but only when they are all loaded.
When I start the animation with images still loading, it looks bad.
The images are dynamically added to the dom by parsing a json requested by javascript on $(document).ready.
After the images are loaded I would like to get a callback.
my core code is like this:
$('.gallery-block').each(function () {
$.ajax({
url: $(this).data("url"),
dataType: 'json',
outerthis: this,
success: function (json) {
$(this.outerthis).data("json", json);
var i = json.length;
while (i--) {
var preload = new Image();
preload.src = json[i];
}
$(this.outerthis).data("loaded", "true");
}
});
});
As you can see I'm trying to preload the images, but I don't know how fickle they are this way. They are not attached to the dom or anything.
The other problem is that I wnat the line
$(this.outerthis).data("loaded", "true");
only to be executed when the images are really preloaded.
Should I iterate a variable on every image's callback?
And probably this.outerthis is a bad design pattern, but I'm new to javascript.
The images don't need to be connected to the DOM to be loaded. What you can do is hook up an onload event to each image (before you set the URL), which will acts as your callback. Just count up the number of responses to onload and you can figure out when they're all loaded.
Something like this (untested):
var i, image,
preload = [], loaded = 0,
images = ["a", "b"], count = images.length;
for(i = 0; i < count; i++) {
image = new Image();
image.onload = onImageLoaded;
image.src = images[i] + ".jpg";
preload[i] = image;
}
function onImageLoaded() {
loaded++;
if(loaded === count) {
alert("done");
}
}

load remote images via Javascript, then selectively add to array

Using javascript I'm trying to load images not on the current page (from an array of image links) and if they are large enough, add them to an array. I'm executing this after the current page has loaded, though a bookmarklet, or firebug console. Using FF.
The closest I've come is the below, but this does not seem to work, and I'm guessing this is because the size test is running before the images have loaded. Apparently my attempt to fix this with 'onload' does not work. How can I fix this up, or is there a better/simpler way to accomplish this task?
(function() {
//create array for the images
var imageArray = new Array();
function loadIfBig(x){
if (x.height > 299 && x.width > 299 && (x.height > 399 || x.width > 399)) {
imageArray.push(x);
//dispImage = '<img src=' + x.src + '><br>';
//document.write('<center>' + dispImage + '</center>');
}
return true;
}
//given an array of imageLinks:
for (x in imageLinks){
//create an image form link and add to array if big enough
im = document.createElement('img');
im.src = imageLinks[x];
im.onload = loadIfBig(im);
}
//view results:
for (x in imageArray){
disp_image = '<img src='+imageArray[x].src+'><br>';
document.write('<center>'+disp_image+'</center>');
}
})();
Update:
Thanks! sure you're right and I'm missing something stupid here, but I made the change you suggested, and then pulled writing the elements into loadIfBig, but it doesn't seem to be executing that function. current code below, including a couple sample input links:
(function() {
var imageArray = new Array();
var imageLinks = ['http://1.bp.blogspot.com/_mfMRTBDpgkM/SwCwu1RPphI/AAAAAAAAJpw/v9YInFBW84I/s1600/800px-San_Francisco_in_ruin_edit2.jpg','http://2.bp.blogspot.com/_mfMRTBDpgkM/SwCwulSZ_yI/AAAAAAAAJpo/NsRcJdpz4Dk/s1600/San_Francisco_PC_59.jpg']
function loadIfBig(x){
if (x.height > 299 && x.width > 299 && (x.height > 399 || x.width > 399)) {
imageArray.push(x);
dispImage = '<img src=' + x.src + '><br>';
document.write('<center>' + dispImage + '</center>');
}
return true;
}
processImages = function(){
for (x in imageLinks) {
//create an image from link and add to array if big enough
im = document.createElement('img');
im.src = imageLinks[x];
im.onload = function(){
loadIfBig(this);
}
}
}
})();
Your fix doesn't work because you're actually executing it immediately.
im.onload = loadIfBig(im) is actually running the function.
What you can do is something like:
im.onload = function() {
loadIfBig(this);
}
Another problem is the fact that you're running through the array of big images before the onload callbacks have actually executed. That needs to be stuck in a different function and called once all the onloads are done.

How do I know a a batch of images are loaded?

I have a Javascript Map kit, and it use Image object to load images. Every time I move/resize the map, it will load many images. But I want to know how I can fire a function when all images are loaded after I do a move/resize action.
Is there a way that I can create a listener like "allimages.onload=function(){}" ?
Or is there any workaround?
You would have to maintain a count of how many images were yet to load, and call the final function when the outstanding image count reached 0. eg.
function nofunction() {}
function loadImages(srcs, callback) {
var images= [];
var imagen= srcs.length;
for (var i= 0; i<srcs.length; i++) {
var image= new Image();
image.onload=image.onerror= function() {
imagen--;
if (imagen==0) {
this.onload=this.onerror= nofunction;
callback();
}
};
image.src= srcs[i];
images.push(image);
}
return images;
}
...
var images= loadImages(['/img/1.gif', '/img/2.gif'], function() {
alert('yay');
});
for (var i= 0; i<images.length; i++)
mapelement.appendChild(images[i]);
A while ago I have written a blog post about detecting the load of a single image. You can use the example to build your function that checks if all images are loaded. I hope it will help.

Categories