Javascript image width is 0 on load - javascript

I have this code for loading several images:
const imageURLS = ["lvls/1.png", "assets/tileatlas.png"];
let imageCount = imageURLS.length;
let assets = [];
function imageLoaded(i){
imageCount--;
if(imageCount == 0){
window.TILEATLAS = assets[0];
load();
}
}
function loadAssets(){
for(let i = 0, len = imageCount; i < len; i++){
let image = new Image();
image.src = imageURLS[i];
assets.push(image);
image.onload = imageLoaded(image);
}
}
onload = loadAssets();
but when I try to access the images in the load() functions, it says the width and height are 0, for me indicating the images aren't finished loading, but they should be? I'm dumbfounded...

The problem is this line:
image.onload = imageLoaded(image);
Because you have the parenthesis, Javascript calls the function immediately and expects it to return the result that will be passed to the onload
You need something like this:
const imageURLS = ["lvls/1.png", "assets/tileatlas.png"];
let imageCount = imageURLS.length;
let assets = [];
function imageLoaded(){
var i = this
imageCount--;
if(imageCount == 0){
window.TILEATLAS = assets[0];
load();
}
}
function loadAssets(){
for(let i = 0, len = imageCount; i < len; i++){
let image = new Image();
image.src = imageURLS[i];
assets.push(image);
image.onload = imageLoaded.bind(image);
}
}
onload = loadAssets();
The bind function sets the value of this in the function to the argument. This way, it won't call the function, but create it.

Related

How to Change the Source of an Image W/JS

I have to change the src of an image using java script and I am pretty sure i hit a road block, in the html I have 3 li elements and in the id is the source of the mouseenter img. I feel like I am close but so far. Heres my code so far. Thanks for any help!
Javascript:
var $ = function (id) {
return document.getElementById(id);};
window.onload = function () {
var links = document.getElementsByTagName("li"),
imgElements = document.getElementsByTagName("img"),
imgNode,
i,
URLone,
URLtwo,
link,
image;
for (i = 0; i < imgElements.length; i++) {
imgNode = imgElements[i];
}
imgNode.mouseenter = function () {
var img = this;
URLtwo = img.getAttribute('id');
img.src = URLtwo;
}
imgNode.mouseout = function () {
var img = this;
URLone = img.getAttribute('src');
img.src = URLone;
};
//preload
for (i = 0; i < links.length * 2; i++) {
link = links[i];
image = new Image();
image.src = link.src;
image = new Image();
image.src = link.id;
}};
HTML ::
<body>
<section>
<h1>Ram Tap Combined Test</h1>
<ul id="image_rollovers">
<li><img src="images/h1.jpg" alt="" id="images/h4.jpg"></li>
<li><img src="images/h2.jpg" alt="" id="images/h5.jpg"></li>
<li><img src="images/h3.jpg" alt="" id="images/h6.jpg"></li>
</ul>
</section>
Working jQuery :
$(document).ready(function() {
$("#image_rollovers img").each(function() {
var oldURL = $(this).attr("src"); // gets the src attribute
var newURL = $(this).attr("id"); // gets the id attribute
// preload images
var rolloverImage = new Image();
rolloverImage.src = newURL;
$(this).hover(
function() {
$(this).attr("src", newURL); // sets the src attribute
},
function() {
$(this).attr("src", oldURL); // sets the src attribute
}
); // end hover
}); // end each
}); // end ready
for (i = 0; i < imgElements.length; i++) {
(function(imgNode) {
imgNode.addEventListener("mouseenter", function () {
var img = this;
URLtwo = img.getAttribute('id');
img.src = URLtwo;
}, false);
imgNode.addEventListener("mouseout", function () {
var img = this;
URLone = img.getAttribute('src');
img.src = URLone;
}, false);
})(imgElements[i]);
}
A couple of problems in your code.
First for loop closing right away, instead should close after your
imgNode.mouseout function
for (i = 0; i < imgElements.length; i++) {
imgNode = imgElements[i];
imgNode.mouseenter = function () {
var img = this;
URLtwo = img.getAttribute('id');
img.src = URLtwo;
}
imgNode.mouseout = function () {
var img = this;
URLone = img.getAttribute('src');
img.src = URLone;
};
}
//preload
for (i = 0; i < links.length * 2; i++) {
link = links[i];
image = new Image();
image.src = link.src;
image = new Image();
image.src = link.id;
}};
Last for loop runs 6 times but there are only 3 tags in html. When it coming to loop no. 3 it doesn't get any value for link.src.
Also links variable provides a collection of 'li' tags and not 'img', last for loop requires src from link.src which doesn't have any value, need to change
var links = document.getElementsByTagName("li"),
to
var links = document.getElementsByTagName("img"),
Try that. Hopefully after correcting above errors your code should work.

Display images from array, let user pick one and change image in node

OK, so, I am trying to allow a user to see a choice of images and click one to change the image in the table. The way it is currently merely adds the last image of the array. I know why this is (I think!), but struggling to find a solution. See comments. As always, all help appreciated.
for (r = 0; r < howOften; r++) {
row = table.insertRow(-1);
for (c = 0; c < numDays; c++) {
col = row.insertCell(-1);
img = new Image();
img.src = "../www/images/TEST.png";
col.appendChild(img);
img.onclick = function () {
var myImages = new Array();
myImages[0] = "../www/images/TEST3.png";
myImages[1] = "../www/images/TEST4.png";
myImages[1] = "../www/images/TEST2.png";
for (var i = 0; i < myImages.length; i++) {
var allImages = new Image();
allImages.src = myImages[i]; //I want to display this array to user somehow
//and for them to be able to choose one and for this.src to point to that.
var gogetImages = allImages.src;
this.src = (gogetImages); //I know this is wrong
};
};
};
};
//LATEST VERSION STARTS FROM HERE
function addImage (col) {
var img = new Image(); // Note that a new img variable will be declared each time this function is called
img.src = "../www/images/TEST.png";
col.appendChild(img);
img.onclick = function () {
var myImages = new Array();
myImages[0] = "../www/images/TEST3.png";
myImages[1] = "../www/images/TEST2.png";
myImages[2] = "../www/images/TEST4.png";
for (var i = 0; i < myImages.length; i++) {
var allImages = new Image();
allImages.src=myImages[i];
var newList = document.createElement("ul");
var newContent = allImages;
newList.appendChild(newContent);
my_div = document.getElementById("showPics");
document.body.insertBefore(newList, my_div);
};
allImages.onclick = function(){
alert("the click is working");//it is but only for the last image...grrrrr
//this.src = ????;
};
};
};
for (r = 0; r < howOften; r++) {
row = table.insertRow(-1);
for (c = 0; c < numDays; c++) {
col = row.insertCell(-1);
addImage(col);
};
};
document.getElementById('holdTable').appendChild(table);
};
Well, in your case,
you are using img = new Image();
Assigning a value to a variable without declaring it "with a var inside a function" creates a global variable.
So, in your code, you are creating a global "img" variable and re-assigning it to a new image which is causing problems for you.
I would suggest you to split up code into a function as below.
function addImage (col) {
var img = new Image(); // Note that a new img variable will be declared each time this function is called
img.src = "../www/images/TEST.png";
col.appendChild(img);
img.onclick = function () {
var myImages = new Array();
myImages[0] = "../www/images/TEST3.png";
myImages[1] = "../www/images/TEST4.png";
myImages[1] = "../www/images/TEST2.png";
for (var i = 0; i < myImages.length; i++) {
var allImages = new Image();
allImages.src = myImages[i]; //I want to display this array to user somehow
//and for them to be able to choose one and for this.src to point to that.
var gogetImages = allImages.src;
this.src = (gogetImages); //I know this is wrong
};
};
}
for (r = 0; r < howOften; r++) {
row = table.insertRow(-1);
for (c = 0; c < numDays; c++) {
col = row.insertCell(-1);
addImage(col);
};
};
Hope it works fine for you now.

Change node image with image from array onclick

I am displaying the images from the array. I want the user to be able to choose an image from the array and for it to replace the current image img.src in the table. I have managed to show the user the image choices when a cell is clicked, but unsure where to go from here. I have tried a clickhandler on the array image but the alert is only showing when last image in array is clicked. Confused. All help appreciated.
function addImage (col) {
var img = new Image(); // Note that a new img variable will be declared each time this function is called
img.src = "../www/images/TEST.png";
col.appendChild(img);
img.onclick = function () {
var myImages = new Array();
myImages[0] = "../www/images/TEST3.png";
myImages[1] = "../www/images/TEST2.png";
myImages[2] = "../www/images/TEST4.png";
for (var i = 0; i < myImages.length; i++) {
var allImages = new Image();
allImages.src=myImages[i];
var newList = document.createElement("ul");
var newContent = allImages;
newList.appendChild(newContent);
my_div = document.getElementById("showPics");
document.body.insertBefore(newList, my_div);
};
allImages.onclick = function(){
alert("the click is working");//it is but only for the last image...grrrrr
};
//this.src = ????;
};
};
for (r = 0; r < howOften; r++) {
row = table.insertRow(-1);
for (c = 0; c < numDays; c++) {
col = row.insertCell(-1);
addImage(col);
};
};
document.getElementById('holdTable').appendChild(table);
};
For starters, you need to move your click assignment inside your loop:
function addImage(col) {
var img = new Image(); // Note that a new img variable will be declared each time this function is called
img.src = "../www/images/TEST.png";
col.appendChild(img);
img.onclick = function() {
var myImages = new Array();
myImages[0] = "../www/images/TEST3.png";
myImages[1] = "../www/images/TEST2.png";
myImages[2] = "../www/images/TEST4.png";
for (var i = 0; i < myImages.length; i++) {
var allImages = new Image();
allImages.src = myImages[i];
var newList = document.createElement("ul");
var newContent = allImages;
newList.appendChild(newContent);
my_div = document.getElementById("showPics");
document.body.insertBefore(newList, my_div);
allImages.onclick = function(e) {
img.src = e.target.src;
};
};
//this.src = ????;
};
};
for (r = 0; r < howOften; r++) {
row = table.insertRow(-1);
for (c = 0; c < numDays; c++) {
col = row.insertCell(-1);
addImage(col);
};
};
document.getElementById('holdTable').appendChild(table);
};
...but the code you have will re-assign your click handlers every time an image is clicked, as well as recreating your DOM (HTML) elements. You might want to consider instead having it only hide/show my_div on subsequent clicks.

How to check if the image is loaded?

with ajax i get an array of pictures URL and then I need to create from them the gallery. I also need to make a counter that shows the number of downloaded images, it looks like this:
var images;
var load_image = new Image();
load_image.onload = function(){
myPhotoSwipe.show(0);
}
$.each(images['images'], function(key, value) {
load_image.src = ('index.php?load_image=' + value);
$('#image_count').remove();
$('span[class="loading"]').after('<div id="count"><h6>Images: ['+key+' / '+images_array['images'].length+']</h6></div>');
images+= '<li><img src="index.php?load_image='+value+'" /></li>';
});
The problem is that the counter is always loaded at penultimate element and stay there until all images are loaded, but I need to show the load of each like a progress.
P.S.
I also tried complete, but it didn't help.
This should fix it. The reason is because the load handler was being bound to only 1 image object.
var images;
$.each(images['images'], function(key, value) {
var load_image = new Image();
load_image.src = ('index.php?load_image=' + value);
$('#image_count').remove();
$('span[class="loading"]').after('<div id="count"><h6>Images: ['+key+' / '+images_array['images'].length+']</h6></div>');
images+= '<li><img src="index.php?load_image='+value+'" /></li>';
load_image.onload = function(){
myPhotoSwipe.show(0);
}
});
You are almost there.
The problem is that you are re-using the same image object. You need to create an array of load_image instances and increment your counter inside onload, when each of them returns.
function load(){
var imageUrls = [];
imageUrls.push('http://www.nasa.gov/images/content/690106main_iss033e005644_full.jpg');
imageUrls.push('http://www.nasa.gov/images/content/690669main_201209210010_full.jpg');
imageUrls.push('http://www.nasa.gov/images/content/691806main_hs3_full_full.jpg');
imageUrls.push('http://www.nasa.gov/images/content/689231main_Webb_Mirror_Cans_orig_full.jpg');
var images = [];
var i;
var counter = 0;
var mainDiv = document.getElementById('somediv');
var counterDiv = document.getElementById('counter');
for (i = 0; i < imageUrls.length; i++)
{
images[i] = new Image();
images[i].width = 100;
images[i].height = 100;
images[i].onload = function () {
counter++;
counterDiv.innerText = counter;
}
mainDiv.appendChild(images[i]);
images[i].src = imageUrls[i];
}
}

Preloading images with javascript does not work

I'm trying to preload images with javascript:
$(document).ready(function () {
preloadImages(
['../../Content/Resources/close_mouse_over.png',
'../../Content/Resources/close.png']);
});
function preloadImages(sources) {
var image = new Array();
for (var i = 0; i < sources.length; i++) {
image[i] = new Image();
image[i].src = sources[i];
}
}
function mouseOverForImage(imgId, imgSrcs) {
document.getElementById(imgId).src = imgSrcs;
}
In Html:
<input type="image" src="../../Content/Resources/close.png" name="Action" value="Save" onmouseover="mouseOverForImage('close', '../../Content/Resources/close_mouse_over.png')"
onmouseout = "mouseOverForImage('close', '../../Content/Resources/close.png')" id="close" title = "Close" />
But request is still sending to server after mouseover. Is not working only in chrome
As noted within my comment, you are passing an array of arrays to the preLoadImages method.
As a result, you are passing an array to image[i].src which means it won't get loaded.
Try
$(document).ready(function () {
preloadImages(
['../../Content/Resources/close_mouse_over.png', '../../Content/Resources/close.png']);
});
function preloadImages(sources) {
var image = new Array();
for (var i = 0; i < sources.length; i++) {
image[i] = new Image();
image[i].src = sources[i];
}
}
function mouseOverForImage(imgId, imgSrcs) {
document.getElementById(imgId).src = imgSrcs;
}
or, if you want to keep the array of array's, then use
function preloadImages(sources) {
var image = new Array();
for (var i = 0; i < sources.length; i++) {
image[i] = new Image();
image[i].src = sources[i][0];
}
}
Edit, on further investigation, a possible cause is preloadImages destroys the image array after preloading the images.
try this instead:
function preloadImages(sources) {
window.preloadedImages = new Array();
for (var i = 0; i < sources.length; i++) {
window.preloadedImages[i] = new Image();
window.preloadedImages[i].src = sources[i];
}
}
This stores the preloaded images within the window object, allowing them to preload properly.
Hope that helps?

Categories

Resources