How to check if the image is loaded? - javascript

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];
}
}

Related

How to set src to each shuffled image in javascript?

I'm trying to shuffle images from array to a specific div.
<body>
<div id="set"></div>
</body>
<script>
var ArrayOfImages = ['bar.jpg',
'foo.jpg',
'koo.jpg',
'too.jpg'
];
var set = document.getElementById("set");
set.addEventListener("click", randomize, false);
ArrayOfImages.forEach(function(image) {
var elem = document.createElement('img');
elem.src = image;
set.appendChild(elem);
});
function shuffle(array) {
let counter = array.length;
// While there are elements in the array`enter code here`
while (counter > 0) {
// Pick a random index
let index = Math.floor(Math.random() * counter);
// Decrease counter by 1
counter--;
// And swap the last element with it
let temp = array[counter];
array[counter] = array[index];
array[index] = temp;
}
return array;
}
function randomize() {
set.innerHTML = shuffle(ArrayOfImages);
}
</script>
Now the problem is, that innerHTML only changes the text of the image but cannot set an src to it. Though it does the shuffle.
Any help would be appreciated!
.innerHTML will change the actual HTML, not the images src which is what you want to change.
At the moment you are getting your image elements from your HTML using
document.getElementById('set)
however, you HTML can only have one element with the id set. Thus, you can use the class attribute instead to give multiple elements the identifier of 'set' and get all your image elements using:
document.getElementsByClassName('set')
which will return a collection of your HTML image tags. Now, to change each image's source you can loop over this collection or loop over your shuffled images and set each image's source.
See an example below for further clarification:
var img_elems = document.getElementsByClassName('set'); // Get all elements to set the image to
// To go into your randomize() function:
// Shuffled images returned via your shuffle() function
var shuffled_images = ['https://images.pexels.com/photos/34950/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350', 'https://www.pandotrip.com/wp-content/uploads/2018/09/Seigantoji-Pagoda-and-Nachi-Falls-in-Nacho-Japan.jpg', 'https://www.elastic.co/assets/bltada7771f270d08f6/enhanced-buzz-1492-1379411828-15.jpg'];
for (var i = 0; i < shuffled_images.length; i++) {
img_elems[i].src = shuffled_images[i]; // Set the image to the src value.
}
/* Ignore this */
img {
height: 200px;
width: 200px;
}
<img src="" class="set" /><br />
<img src="" class="set" /><br />
<img src="" class="set" />
More clean and better way of doing it in vanilla javascript.
The issue was in your shuffle function.
var image_swap_tool = function(options){
var self = this;
self.ArrayOfImages = options.ArrayOfImages;
self.image_container_elem = document.getElementById("set");
self.image_container_elem.addEventListener("click", function(){
self.randomize();
});
}
image_swap_tool.prototype.create_image = function(){
var self = this;
var images = self.ArrayOfImages;
var image_container = self.image_container_elem;
image_container.innerHTML = '';
for(var i=0; i < images.length;i++){
var img = document.createElement('img');
img.setAttribute('src',images[i]);
image_container.appendChild(img);
}
};
image_swap_tool.prototype.shuffle = function(){
var self = this;
var images = self.ArrayOfImages;
let counter = images.length;
while (counter > 0) {
// Pick a random index
let index = Math.floor(Math.random() * counter);
// Decrease counter by 1
counter--;
// And swap the last element with it
let temp = images[counter];
images[counter] = images[index];
images[index] = temp;
}
//Set new order back to images for next time
self.ArrayOfImages = images;
//Images are shuffled then append them again
self.create_image();
}
image_swap_tool.prototype.randomize = function(){
var self = this;
var image_container = self.image_container_elem;
self.shuffle();
}
var options = {};
options.ArrayOfImages = ['bar.jpg', 'foo.jpg', 'koo.jpg', 'too.jpg'];
var tool = new image_swap_tool(options);
tool.create_image();
Thanks

I don't how why my backgroundImage doesn't work

Why does my banner doesn't change her background? Please help me.
When I run the file the console tells me:
Uncaught TypeError: flechedroite.addEventListener is not a function
I really don't understand. I'm a beginner in Javascript so please explain me with kind words how I can fix this error :)
var flechedroite = document.getElementsByClassName('fa-arrow-right');
var flechegauche = document.getElementsByClassName('switch-left');
var banner = document.getElementById('banner');
var images = [];
var changeBackground = function (bElement, bUrl) {
return bElement.style.backgroundImage = "url(" + bUrl + ")";
}
//image list
images[0] = 'images/image1.jpg';
images[1] = 'images/image2.jpg';
images[2] = 'images/image3.jpg';
flechedroite.addEventListener('click', function() {
for (var i = 0; i < images.length; i++) {
changeBackground(document.body, images[i]);
}
})
addEventListener should be called in window.onload or in $(document).ready()
Since getElementsByClassName returns an array, you need to use array index with flechedroite to add an event listener. i.e. flechedroite[0].addEventListener('click', function() {...});
You are calling changeBackground function in a loop to set the background image, effectively you will see only the last image from the array being set as background.
JS Code
var images = [];
var changeBackground = function (bElement, bUrl) {
return bElement.style.backgroundImage = "url("+bUrl+")";
}
//image list
images[0] = 'https://www.gettyimages.ie/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg';
images[1] = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTOGUhZo0Qe81U5qY_Z-seXgsD79LEEet832TVOlLMOEy10ZPsV';
images[2] = 'https://cdn.pixabay.com/photo/2016/06/18/17/42/image-1465348_960_720.jpg';
window.onload = function(){
var flechedroite = document.getElementsByClassName('fa-arrow-right');
var flechegauche = document.getElementsByClassName('switch-left');
var banner = document.getElementById('banner');
var currentImageIndex = 0;
flechedroite[0].addEventListener('click', function() {
currentImageIndex = (currentImageIndex+1)%images.length;
changeBackground(document.body, images[currentImageIndex]);
})
}
The function getElementsByClassName returns a HTMLCollection, which is an array like structure that can contain multiple elements. So you need to use an index to access the elements contained in it.
So flechedroite.addEventListener results in an error but flechedroite[0].addEventListener should work
https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByClassName
if you use 'getElementsByClassName' and you want to add an 'addEventListener', you can not do it in a 'generic' way: "flechedroite.addEventListener ('click', function () {}". You have to do this for each element:
var flechedroite = document.getElementsByClassName('fa fa-arrow-right');
//flechedroite contains all the elements that have the 'fa fa-arrow-right' classes
//on each element you have to add the "addEventListener"
for (var i = 0; i < flechedroite.length; i++) {
flechedroite[i].addEventListener('click', function() {
alert('flechedroite');
});
}
basic example JSFiddle1
a more advanced example
JSFiddle2

Using a loop, but only one element is being added

I was working on some JavaScript and was trying to add things dynamically. Below is my code. My problem is that I am trying to add three "li" elements, attach "img" tags to it ans attaching the src dynamically. But it is attaching only the last image i.e in my code "bid_3" to all the "li". Help appreciated.
(function() {
var bxSlider = document.createElement("ul"); //created ul
bxSlider.setAttribute("class", "bxslider"); // gave a class name bxslider.
for (i = 1; i < 4; i++) {
var itemsList = document.createElement("li");
var linkImages = document.createElement("img");
linkImages.src = "images/bid_" + i + ".jpg";
itemsList.appendChild(linkImages);
}
bxSlider.appendChild(itemsList);
document.body.appendChild(bxSlider); //append everything to the body.
var ulNum = document.getElementsByTagName("ul");
alert(ulNum.length); // should return 1
var liNum = document.getElementsByTagName("li");
alert(liNum.length); // should return 3
var imgNum = document.getElementsByTagName("img");
alert(imgNum.length); //should return 3
//call the slider.
$(document).ready(function() {
$('.bxslider').bxSlider();
});
}());
PS:- I am not a JavaScript expert. Please forgive if my code is bad.
You're only attaching itemsList after you've passed through the loop. Try this:
// Before loop stuff...
for (i = 1; i < 4; i++) {
var itemsList = document.createElement("li");
var linkImages = document.createElement("img");
linkImages.src = "images/bid_" + i + ".jpg";
itemsList.appendChild(linkImages);
bxSlider.appendChild(itemsList);
}
// After loop stuff...

Showing an image from an array of images - Javascript

I have a large image which is shown on my homepage, and when the user clicks the "next_img" button the large image on the homepage should change to the next image in the array.
However, the next arrow when clicked does nothing, and the main image on the homepage does not change.
I need to do this in javascript.
In the HTML:
<!--Main Content of the page -->
<div id="splash">
<img src="images/img/Splash_image1.jpg" alt="" id="mainImg">
</div>
<div id="imglist">
<img src="images/next_img.png" alt="">
And then in the javascript file:
var imgArray = new Array();
imgArray[0] = new Image();
imgArray[0].src = 'images/img/Splash_image1.jpg';
imgArray[1] = new Image();
imgArray[1].src = 'images/img/Splash_image2.jpg';
imgArray[2] = new Image();
imgArray[2].src = 'images/img/Splash_image3.jpg';
imgArray[3] = new Image();
imgArray[3].src = 'images/img/Splash_image4.jpg';
imgArray[4] = new Image();
imgArray[4].src = 'images/img/Splash_image5.jpg';
imgArray[5] = new Image();
imgArray[5].src = 'images/img/Splash_image6.jpg';
/*------------------------------------*/
function nextImage(element)
{
var img = document.getElementById(element);
for(var i = 0;i<imgArray.length;i++)
{
if(imgArray[i] == img)
{
if(i == imgArray.length)
{
var j = 0;
document.getElementById(element).src = imgArray[j].src;
break;
}
else
var j = i + 1;
document.getElementById(element).src = imgArray[j].src;
break;
}
}
}
Any help would be appreciated. Thanks.
Just as Diodeus said, you're comparing an Image to a HTMLDomObject. Instead compare their .src attribute:
var imgArray = new Array();
imgArray[0] = new Image();
imgArray[0].src = 'images/img/Splash_image1.jpg';
imgArray[1] = new Image();
imgArray[1].src = 'images/img/Splash_image2.jpg';
/* ... more images ... */
imgArray[5] = new Image();
imgArray[5].src = 'images/img/Splash_image6.jpg';
/*------------------------------------*/
function nextImage(element)
{
var img = document.getElementById(element);
for(var i = 0; i < imgArray.length;i++)
{
if(imgArray[i].src == img.src) // << check this
{
if(i === imgArray.length){
document.getElementById(element).src = imgArray[0].src;
break;
}
document.getElementById(element).src = imgArray[i+1].src;
break;
}
}
}
Here's a somewhat cleaner way of implementing this. This makes the following changes:
The code is DRYed up a bit to remove redundant and repeated code and strings.
The code is made more generic/reusable.
We make the cache into an object so it has a self-contained interface and there are fewer globals.
We compare .src attributes instead of DOM elements to make it work properly.
Code:
function imageCache(base, firstNum, lastNum) {
this.cache = [];
var img;
for (var i = firstNum; i <= lastnum; i++) {
img = new Image();
img.src = base + i + ".jpg";
this.cache.push(img);
}
}
imageCache.prototype.nextImage(id) {
var element = document.getElementById(id);
var targetSrc = element.src;
var cache = this.cache;
for (var i = 0; i < cache.length; i++) {
if (cache[i].src) === targetSrc) {
i++;
if (i >= cache.length) {
i = 0;
}
element.src = cache[i].src;
return;
}
}
}
// sample usage
var myCache = new imageCache('images/img/Splash_image', 1, 6);
myCache.nextImage("foo");
Some advantages of this more object oriented and DRYed approach:
You can add more images by just creating the images in the numeric sequences and changing one numeric value in the constructor rather than copying lots more lines of array declarations.
You can use this more than one place in your app by just creating more than one imageCache object.
You can change the base URL by changing one string rather than N strings.
The code size is smaller (because of the removal of repeated code).
The cache object could easily be extended to offer more capabilities such as first, last, skip, etc...
You could add centralize error handling in one place so if one image doesn't exist and doesn't load successfully, it's automatically removed from the cache.
You can reuse this in other web pages you develop by only change the arguments to the constructor and not actually changing the implementation code.
P.S. If you don't know what DRY stands for, it's "Don't Repeat Yourself" and basically means that you should never have many copies of similar looking code. Anytime you have that, it should be reduced somehow to a loop or function or something that removes the need for lots of similarly looking copies of code. The end result will be smaller, usually easier to maintain and often more reusable.
Also, when checking for the last image, you must compare with imgArray.length-1 because, for example, when array length is 2 then I will take the values 0 and 1, it won't reach the value 2, so you must compare with length-1 not with length, here is the fixed line:
if(i == imgArray.length-1)
This is a simple example and try to combine it with yours using some modifications. I prefer you set all the images in one array in order to make your code easier to read and shorter:
var myImage = document.getElementById("mainImage");
var imageArray = ["_images/image1.jpg","_images/image2.jpg","_images/image3.jpg",
"_images/image4.jpg","_images/image5.jpg","_images/image6.jpg"];
var imageIndex = 0;
function changeImage() {
myImage.setAttribute("src",imageArray[imageIndex]);
imageIndex = (imageIndex + 1) % imageArray.length;
}
setInterval(changeImage, 5000);
Here's your problem:
if(imgArray[i] == img)
You're comparing an array element to a DOM object.
<script type="text/javascript">
function bike()
{
var data=
["b1.jpg", "b2.jpg", "b3.jpg", "b4.jpg", "b5.jpg", "b6.jpg", "b7.jpg", "b8.jpg"];
var a;
for(a=0; a<data.length; a++)
{
document.write("<center><fieldset style='height:200px; float:left; border-radius:15px; border-width:6px;")<img src='"+data[a]+"' height='200px' width='300px'/></fieldset></center>
}
}

Accessing functions from within a Javascript Object (Javascript)

I am attempting to create a basic Hangman program. It's an array of tags which are assigned into an array of Objects (called Buttons). Each image is an image of a letter, so for example you would press the 'L' button, it would check whether this was in an WordArray (which is an array of chars), then it would act accordingly (to hide the letter, then update the gallows image if it needed to).
I cannot get the onclick method of the images to access the checkinarray function. What am i doing wrong?
var LetterAmount = 3; //make this 26. checked.
var WordArray = new Array();
var Buttons = new Array();
function checkinarray(num){
var z = 0;
while (z<4){
document.write("looping through word now");
if (num == WordArray[z]){
document.write("<br/>it is in the word");
}
z++;
}
}
function ButtonClicked(){
this.Image.src = "images/blank.jpg";
checkinarray(this.Number);
}
function Button(Image, Number) {
this.Image = Image;
this.Number = Number;
this.ButtonClicked = ButtonClicked;
}
function initialiseletters(){
var x;
//set up empty img tags for use
for(i = 0; i < LetterAmount; i++) {
document.write("<img id=" + i + ">");
}
for(x = 0; x < LetterAmount; x++) {
document.images[x].src = "images/" + x + ".jpg";
document.getElementById(x).onclick =function(){
Buttons[this.id].ButtonClicked();
}
Buttons[x] = new Button(document.images[x], "" + x);
}
}
function initialiseword(){
//WordArray = new Array();
WordArray[0] = 0;
WordArray[1] = 1;
WordArray[2] = 2;
WordArray[3] = 3;
}
function initialise(){
initialiseword();
initialiseletters();
document.write("testing overall");
}
I'm not seeing a problem with ButtonClicked calling checkinarray, but I'm seeing a problem with checkinarray -- it's calling document.write after the page rendering is complete (e.g., when the user clicks), which won't work. You need to modify the DOM via DOM methods (this will be made much easier if you use a toolkit like Prototype, jQuery, MooTools, Dojo, the Closure Library, YUI, etc.).
document.getElementById(x).onclick =function(){
Buttons[this.id].ButtonClicked();
}
Is where your problem is. 'this.id' is undefined.
document.write is not a good way to add elements to the DOM... Try document.createElement('img');
Then you already have reference to the image like so:
var img = document.createElement('img');
img.onclick = function()
{
//your click...
}
//add it to the view stack
document.body.appendChild(img);

Categories

Resources