Pop up images on the page every few seconds - javascript

I have a page function that shows and hides images every 5 seconds.
Instead of these two images, I need to open random images from the list each time.
I added an array with images, tried to add the creation of an image in the popup() function, and the removal of the hidePopup() function, but nothing happened.
var images = new Array("http://dummyimage.com/100x100/100/fff",
"http://dummyimage.com/100x100/304/fff",
"http://dummyimage.com/100x100/508/fff",
"http://dummyimage.com/100x100/70B/fff",
"http://dummyimage.com/100x100/90F/fff",
"http://dummyimage.com/100x100/AA0/fff",
"http://dummyimage.com/100x100/CB0/fff",
"http://dummyimage.com/100x100/EC0/fff");
var randomImage = Math.floor(Math.random() * images.length);
popup();
function popup() {
document.getElementById("disclaimer").style.display = "block";
setTimeout(hidePopup, 5000);
}
function hidePopup() {
document.getElementById("disclaimer").style.display = "none";
setTimeout(popup, 5000);
}
<div id="disclaimer">
<div><img src="http://dummyimage.com/100x100/100/fff"></div>
<div><img src="http://dummyimage.com/100x100/304/fff"></div>
</div>

In the HTML file you should create a div with an id disclaimer
<div id="disclaimer"></div>
Then in the js file you should select the HTML element out of the popup function
const el = document.getElementById("disclaimer");
And create an enter code hereimage element out of the popup function
const img = document.createElement('img')
Then in the popup function you should create a random image every time the function get called with setTimeout to change the image src, set attribute src for image with random image number from images array, and append an image element to the div in HTML file
and call setTimeout with hidepop
function popup() {
randomImage = Math.floor(Math.random() * images.length)
img.setAttribute('src', images[randomImage])
img.setAttribute('alt', 'random')
el.appendChild(img);
setTimeout(hidePopup, 1000);
}
Then create a hidepop()
function hidePopup() {
setTimeout(popup, 1000);
}
And call popup function
popup()
Note :
In setTimeout function don't call the handler like that
setTimeout(hidePopup(), 1000);
that will cause Maximum call stack size exceeded error and you app will crashed

Set a promise then change the image randomly every N milliseconds.
const images = ["http://dummyimage.com/100x100/100/fff",
"http://dummyimage.com/100x100/304/fff",
"http://dummyimage.com/100x100/508/fff",
"http://dummyimage.com/100x100/70B/fff",
"http://dummyimage.com/100x100/90F/fff",
"http://dummyimage.com/100x100/AA0/fff",
"http://dummyimage.com/100x100/CB0/fff",
"http://dummyimage.com/100x100/EC0/fff"
];
const id = "disclaimer";
const imageElement = document.getElementById(id);
function wait(ms, value) {
return new Promise(resolve => setTimeout(resolve, ms, value));
}
function getRandomImageIndex() {
let randomImageIndex = Math.floor(Math.random() * images.length);
return randomImageIndex;
}
function setImage() {
let index = getRandomImageIndex();
var w = wait(5000, index);
w.then(function(index) {
console.log(index);
imageElement.setAttribute('src', images[index]);
}).then(function() {
imageElement.classList.toggle('hide-me');
return wait(5000, 1);
}).then(function() {
imageElement.classList.toggle('hide-me');
setImage();
});
}
// start it off
setImage();
.hide-me {
display: none;
}
<div id="disclaimer">
<div><img src="http://dummyimage.com/100x100/100/fff" alt="howdy"></div>
</div>

A better way to do this would be to change the source of the image.
var images = new Array("//dummyimage.com/100x100/100/fff",
"//dummyimage.com/100x100/304/fff",
"//dummyimage.com/100x100/508/fff",
"//dummyimage.com/100x100/70B/fff",
"//dummyimage.com/100x100/90F/fff",
"//dummyimage.com/100x100/AA0/fff",
"//dummyimage.com/100x100/CB0/fff",
"//dummyimage.com/100x100/EC0/fff");
popup();
function popup() {
randomImage = images[Math.floor(Math.random()*images.length)];
document.getElementById("changeThis").style.display = "block";
document.getElementById("changeThis").src = randomImage;
setTimeout(hidePopup, 5000);
}
function hidePopup() {
document.getElementById("changeThis").style.display = "none";
setTimeout(popup, 5000);
}
<img src="//dummyimage.com/100x100/100/fff" id="changeThis">
If you would prefer to not have the images disappear, you can remove style.display = "none";, and replace setTimeout(popup, 5000); with popup();
You should replace // with https:// or http:// if this is being accessed as a file.

Related

Add previous and next functions for slideshow with window.onload JavaScript

I want to create a JavaScript program who allow the user to switch between
image by using previous and next button. But i can't use window.onload to load the next image cause window.onload overwrite the previous window.onload. I want to know if their exist any solution to make window.onload work with two functions in the same time. If window.onload can't be usable for this kind of program you can suggest me another solution.
Thank you.
var i =0;
var image = [];
image[0]= 'image.jpg';
image[1]= 'image2.jpg';
image[2]= 'panther.jpg'
function next(){
document.slide.src = image[i];
if(i<image.length-1){
i++;
}
else{
i=0;
}
document.getElementById('bouton1').addEventListener('click',next);
}
function previous(){
document.slide.src = image[i];
if(i>0){
i--;
}
else{
i=image.length-1;
}
document.getElementById('bouton2').addEventListener('click',previous);
}
window.onload = next;
window.onload = previous;
Needed a couple of changes, can you test it like this. Note we changed the onload to attach listeners. See comment.
var i =0;
var image = [];
image[0]= 'image.jpg';
image[1]= 'image2.jpg';
image[2]= 'panther.jpg'
function next(){
document.slide.src = image[i];
if(i<image.length-1){
i++;
}
else{
i=0;
}
}
function previous(){
document.slide.src = image[i];
if(i>0){
i--;
}
else{
i=image.length-1;
}
}
// This is window.onload
(function(){
// Move calls to attach event listeners here
document.getElementById('bouton2').addEventListener('click',previous);
document.getElementById('bouton1').addEventListener('click',next);
})();
addEventListener is a better method for adding an event handler without replacing an existing one.
window.addEventListener('load', e => { /* ... */ });
As a rule of thumb, any on(blah) attributes in the DOM can be replaced with addEventListener(blah, ...).
I'm not exactly sure about your idea behind window.onload, if you want to preload images (so the user does not have to wait for the image to load on buttons click...) than you could use new Image() and something like:
const EL_slide = document.getElementById("slide");
const EL_prev = document.getElementById('prev');
const EL_next = document.getElementById('next');
const image = [
'//placehold.it/800x600/0bf?text=1',
'//placehold.it/800x600/f0b?text=2',
'//placehold.it/800x600/0fb?text=3'
];
const n = image.length;
let i = 0;
// Preload images
image.forEach(src => {
var img = new Image();
img.src = src;
});
// Animation logic
function anim() {
if((/prev|next/).test(this.id)) i = this.id === "next" ? ++i : --i;
i = i<0 ? n-1 : i%n; // Index fixer (prevents out of bound index)
EL_slide.style.backgroundImage = `url('${image[i]}')`
}
// Events
[EL_prev, EL_next].forEach(EL => EL.addEventListener('click', anim));
// Load first!
anim();
#slide {
height: 70vh;
transition: 0.3s;
background: none 50% 50% / cover no-repeat;
}
<button id="prev">←</button>
<button id="next">→</button>
<div id="slide"></div>
and just make sure to place your Javascript right before the closing </body> tag.

JavaScript Timeout reset mechanism

What I want:
There are two pictures that are being switched/swapped every three seconds.
I want to make it so that when the button is clicked, the picture switches and the auto-swap resets. So if the button is clicked, the image swaps and three seconds later, it will auto-swap, until the button is clicked again in which the cycle will repeat.
What I have right now
Currently, the problem is that: when the button is clicked, it messes up the timing of the auto-switches.
Edit:
Please don't create a new code base. Just modify mines. The code doesn't have to be an expert super concise level. I'm only three weeks into JavaScript (and it's my first programming language). I have to explain to classmates and it wouldn't be nice the code had elements I don't understand. So sorry for the inconvenience.
Right now I just need the button to correctly stop and restart the time.
<html>
<head>
<script>
let reset = setTimeout(change, 3000);
function change() {
if(document.getElementById("picture").src == "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350") {
document.getElementById("picture").src = "https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&h=350";
}
else {
document.getElementById("picture").src = "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350";
}
setTimeout(change, 3000);
}
function fastChange() {
clearTimeout(reset);
if(document.getElementById("picture").src == "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350") {
document.getElementById("picture").src = "https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&h=350";
}
else {
document.getElementById("picture").src = "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350";
}
}
</script>
</head>
<body>
<input type="button" onclick="fastChange();">
<img src="https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350" id="picture">
</body>
</html>
The reason why your timer resets is because you are not clearing the timeout.
you need to make a reference to the timeout and then use clearTimeout() on it whne you make the fast change. I don't think it is possible or wise to do that inline the way you have it so you code needs to be refactored
let imgSrc1 = 'https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350'
let imgSrc2 = 'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&h=350'
let imgElement = document.getElementById('picture');
let timeout;
function change() {
if(imgElement.src === imgSrc1) {
imgElement.src = imgSrc2;
} else {
imgElement.src = imgSrc1;
  }
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(change, 3000);
}
You don't even need the second function fastChange. Now you can sent the onClick listener to change() like this
document.getElementById('whatever you want to click').onCLick = change;
Setting and clearing timeouts in multiple places will work, but I prefer using a "main loop" and a variable to count frames.
Here's an example that uses setInterval and resets a timer variable when the button was clicked:
const url1 = "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350";
const url2 = "https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&h=350";
function change() {
picture.src = picture.src == url1 ? url2 : url1;
}
var timer = 0;
setInterval(function() {
timer++;
time.textContent = timer;
if (timer === 30) fastChange();
}, 100);
function fastChange() {
change();
timer = 0;
}
picture.src = url1;
swap.onclick = fastChange;
#picture {
height: 70vh
}
<button id="swap">SWAP</button> <span id="time"></span><br>
<img id="picture">
You can do this by calling setTimeout and updating the index as necessary. Just be sure to store the most recent timeout id so that it can be cancelled on reset using clearTimeout.
// store the reference to the <img> that contains the picture
const pic = document.getElementById('picture')
// store a list (array) of the two picture urls
const sources = [
'https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350',
'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&h=350'
]
// used to store a reference to the interval timer you created.
var lastTimer
// a starting index of the list (i.e. which image we are up to right now)
var index = 1
// this functions swaps the image and sets a timer
function startRotation() {
// update the index to the next one (goes 0-1-0-1->etc)
index = 1 - index
// sets the .src of the image element
pic.src = sources[index]
// starts a 3 second timer to call this same function again
// but also stores a reference to the timer so that it can be cancelled
lastTimer = setTimeout(startRotation, 3000)
}
// this functions resets the timer and restarts the process
function reset() {
// stop the current timer if there is one
if(lastTimer){
clearTimeout(lastTimer)
}
// restart the process
startRotation()
}
// start the swapping process on start
startRotation()
<input type="button" onclick="reset();">
<img id="picture">
NOT HOW YOU CLEARTIMEOUT:
<html>
<head>
<script>
var i;
function change() {
if(document.getElementById("picture").src == "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350") {
document.getElementById("picture").src = "https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&h=350";
}
else {
document.getElementById("picture").src = "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350";
}
i = setTimeout(change, 3000);
}
function fastChange() {
clearTimeout(i);
if(document.getElementById("picture").src == "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350") {
document.getElementById("picture").src = "https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&h=350";
}
else {
document.getElementById("picture").src = "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350";
}
i = setTimeout(change, 3000);
}
</script>
</head>
<body onload="setTimeout(change, 3000)">
<input type="button" onclick="fastChange();">
<img src="https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350" id="picture">
</body>
</html>

Javascript slider loop

I have been trying to create an image slider for html by changing the value of the image element, using a loop to go through each image and then returning to the original image.
However once it reaches the end of the loop it doesn't continue.
Here is my Js code:
window.onload = function() {
var x = 0
while(x<1000){
setTimeout(function() {
document.getElementById('carousel').src='img/header2.jpg';
setTimeout(function() {
document.getElementById('carousel').src='img/header3.jpg';
setTimeout(function() {
document.getElementById('carousel').src='img/header.jpg';
}, 5000);
}, 5000);
}, 5000);
x = x+1
}
}
I'd recommend you to not do while loop in this case. Just recall setTimeout when executed.
window.onload = function() {
/* Element */
var carousel = document.getElementById('carousel'),
/* Carousel current image */
cimage = 2,
/* Carousel source images */
csources = [
'img/header2.jpg',
'img/header3.jpg',
'img/header.jpg'
];
function changeCarouselImage() {
// Reset the current image if it's ultrapassing the length - 1
if(cimage >= 3) cimage = 0;
// Change the source image
carousel.src = csources[cimage ++];
// Re-call the function after 5s
setTimeout(changeCarouselImage, 5000);
}
setTimeout(changeCarouselImage, 5000);
};
The final function does not set another timeout, and thus the animation does not continue. Seperating into individual functions should help:
var carousel = document.getElementById('carousel');
function ani1() {
carousel.src = 'img/header.jpg';
window.setTimeout(ani2, 500);
}
function ani2() {
carousel.src = 'img/header2.jpg';
window.setTimeout(ani3, 500);
}
function ani3() {
carousel.src = 'img/header3.jpg';
window.setTimeout(ani1, 500);
}
window.onload = ani1;

How to Hide an Image, if not clicked, in N seconds?

I have a button that when is clicked, an image is created using javascript and get prepended to a div (adds it inside a div).
var image = new Image();
var imageHtml = image.toHtml();
$('div.board').prepend(imageHtml);
function Image()
{
this.toHtml = function ()
{
return '<img src=\"myImage.png\" width=\"40px\" height=\"40px\" />';
}
}
This image can be clicked in 2 seconds then user will have 1 more score and if not clicked in that time, then the image should disappear.
How to do that in javascript?
Thanks,
function start_game(image){
var timeout = null;
image.onclick = function(){
clearTimeout(timeout);
//addScore();
};
timeout = setTimeout(function(){
image.onclick = null;
image.style.display = "none";
// remove the image from dom if needed;
}, 2000);
}
Demo: http://jsfiddle.net/UpNCb/
see this, just difference is you going to hide instead of link display
or
give id 'img_id' to your image
function hideimage() {
document.getElementById('img_id').style.display = 'none';
}
setTimeout(hideimage, 10000);
Use the function setTimeout() and the CSS property display or visibility.

Checking for multiple images loaded

I'm using the canvas feature of html5. I've got some images to draw on the canvas and I need to check that they have all loaded before I can use them.
I have declared them inside an array, I need a way of checking if they have all loaded at the same time but I am not sure how to do this.
Here is my code:
var color = new Array();
color[0] = new Image();
color[0].src = "green.png";
color[1] = new Image();
color[1].src = "blue.png";
Currently to check if the images have loaded, I would have to do it one by one like so:
color[0].onload = function(){
//code here
}
color[1].onload = function(){
//code here
}
If I had a lot more images, Which I will later in in development, This would be a really inefficient way of checking them all.
How would I check them all at the same time?
If you want to call a function when all the images are loaded, You can try following, it worked for me
var imageCount = images.length;
var imagesLoaded = 0;
for(var i=0; i<imageCount; i++){
images[i].onload = function(){
imagesLoaded++;
if(imagesLoaded == imageCount){
allLoaded();
}
}
}
function allLoaded(){
drawImages();
}
Can't you simply use a loop and assign the same function to all onloads?
var myImages = ["green.png", "blue.png"];
(function() {
var imageCount = myImages.length;
var loadedCount = 0, errorCount = 0;
var checkAllLoaded = function() {
if (loadedCount + errorCount == imageCount ) {
// do what you need to do.
}
};
var onload = function() {
loadedCount++;
checkAllLoaded();
}, onerror = function() {
errorCount++;
checkAllLoaded();
};
for (var i = 0; i < imageCount; i++) {
var img = new Image();
img.onload = onload;
img.onerror = onerror;
img.src = myImages[i];
}
})();
Use the window.onload which fires when all images/frames and external resources are loaded:
window.onload = function(){
// your code here........
};
So, you can safely put your image-related code in window.onload because by the time all images have already loaded.
More information here.
A hackish way to do it is add the JS command in another file and place it in the footer. This way it loads last.
However, using jQuery(document).ready also works better than the native window.onload.
You are using Chrome aren't you?
The solution with Promise would be:
const images = [new Image(), new Image()]
for (const image of images) {
image.src = 'https://picsum.photos/200'
}
function imageIsLoaded(image) {
return new Promise(resolve => {
image.onload = () => resolve()
image.onerror = () => resolve()
})
}
Promise.all(images.map(imageIsLoaded)).then(() => {
alert('All images are loaded')
})
Just onload method in for loop does not solve this task, since onload method is executing asynchronously in the loop. So that larger images in the middle of a loop may be skipped in case if you have some sort of callback just for the last image in the loop.
You can use Async Await to chain the loop to track image loading synchronously.
function loadEachImage(value) {
return new Promise((resolve) => {
var thumb_img = new Image();
thumb_img.src = value;
thumb_img.onload = function () {
console.log(value);
resolve(value); // Can be image width or height values here
}
});
}
function loadImages() {
let i;
let promises = [];
$('.article-thumb img').each(function(i) {
promises.push(loadEachImage( $(this).attr('src') ));
});
Promise.all(promises)
.then((results) => {
console.log("images loaded:", results); // As a `results` you can get values of all images and process it
})
.catch((e) => {
// Handle errors here
});
}
loadImages();
But the disadvantage of this method that it increases loading time since all images are loading synchronously.
Also you can use simple for loop and run callback after each iteration to update/process latest loaded image value. So that you do not have to wait when smaller images are loaded only after the largest.
var article_thumb_h = [];
var article_thumb_min_h = 0;
$('.article-thumb img').each(function(i) {
var thumb_img = new Image();
thumb_img.src = $(this).attr('src');
thumb_img.onload = function () {
article_thumb_h.push( this.height ); // Push height of image whatever is loaded
article_thumb_min_h = Math.min.apply(null, article_thumb_h); // Get min height from array
$('.article-thumb img').height( article_thumb_min_h ); // Update height for all images asynchronously
}
});
Or just use this approach to make a callback after all images are loaded.
It all depends on what you want to do. Hope it will help to somebody.
try this code:
<div class="image-wrap" data-id="2">
<img src="https://www.hd-wallpapersdownload.com/script/bulk-upload/desktop-free-peacock-feather-images-dowload.jpg" class="img-load" data-id="1">
<i class="fa fa-spinner fa-spin loader-2" style="font-size:24px"></i>
</div>
<div class="image-wrap" data-id="3">
<img src="http://diagramcenter.org/wp-content/uploads/2016/03/image.png" class="img-load" data-id="1">
<i class="fa fa-spinner fa-spin loader-3" style="font-size:24px"></i>
</div>
<script type="text/javascript">
jQuery(document).ready(function(){
var allImages = jQuery(".img-load").length;
jQuery(".img-load").each(function(){
var image = jQuery(this);
jQuery('<img />').attr('src', image.attr('src')).one("load",function(){
var dataid = image.parent().attr('data-id');
console.log(dataid);
console.log('load');
});
});
});
</script>

Categories

Resources