Fading Image Slider - javascript

I'm trying to fade images in and out of each other. I'm not sure if it's better to preload the image before hand or not. Pretty much what's happening is that fade is hitting completely white background before fading in the next image, but I want it to fade immediatly instead of showing the white background - if that makes sense:
$(document).ready(function () {
var $next,
cycle;
var i = 0;
var imgArr = ['1.jpg', '2.jpg', '3.jpg'];
$activeLi = $("#slideshow li");
$activeLi.html('<img src="images/' + imgArr[i] + '" />');
cycle = setInterval(change_img, 1000);
function change_img(){
clearInterval(cycle);
$activeLi.find('img').fadeOut('slow', function(){
$activeLi.html('<img src="images/' + imgArr[i] + '" />').fadeIn('slow');
});
i = (i == (imgArr.length - 1)) ? 0 : ++i;
cycle = setInterval(change_img, 1000);
}
});
Also is it better to prealod my images before fading them in?
JSFiddle
My Solution (Which is jaded sinced I started the question...)
$(document).ready(function () {
var $next,
cycle;
var i = 0;
var durTimer = 2000;
var imgArr = ['1.jpg', '2.jpg', '3.jpg', '4.jpg'];
$activeLi = $("#slideshow li");
$activeLi.first().html('<img src="images/' + imgArr[0] + '" />');
cycle = setInterval(change_img, durTimer);
function change_img(){
clearInterval(cycle);
var nxtImg = (i == imgArr.length) ? 1 : i;
$activeLi.last().html('<img src="images/' + imgArr[nxtImg] + '" />');
$activeLi.find('img').animate({opacity:0}, {duration: durTimer});
i = (i == (imgArr.length - 1)) ? 0 : ++i;
$activeLi.first().html('<img src="images/' + imgArr[i] + '" />');
cycle = setInterval(change_img, durTimer);
}
});

If you have limited number of images, it is better to load all of them on page load.
In the given example, you are using only one img tag and changing the source of that to another image after some time.
So, when the image is faded out, definitely we can see the white background. Also it will take some time to load the new image.
Instead of a single img tag, add three img tags (from your code, there are three images).
Start both the fadeOut and fadeIn animations at a time.
fadeOut for current image and fadeIn for next image.
This will not show any white background.
I already created a small demo for this.
Check this out : http://db.tt/q8VPb03U

Related

setInterval & setTimeout executing at the wrong time

I want to change the background image using setInterval and setTimeout every x seconds but im strugling a bit. The problem is that the timer is not working as supposed to. It changes the images instantly.
let images = ['background1.jpg', 'background2.jpg','background3.jpg'];
let i = 0;
$("main").css("background-image", 'url(' + images[i] + ')');
setInterval(function(){
setTimeout( function() {
if(i == 0){
i++;
$('main').css({
'background-image': 'url(' + images[i] + ')',
'background-size': 'cover'
});
}
},3000);
setTimeout( function() {
if(i == 1){
i++;
$('main').css({
'background-image': 'url(' + images[i] + ')',
'background-size': 'cover'
});
}
},3000);
setTimeout( function() {
if(i == 2){
i = 0;
$('main').css({
'background-image': 'url(' + images[i] + ')',
'background-size': 'cover'
});
}
},3000);
}, 3000);
Get the main element (Or the target)
Declare the CSS background-size': 'cover for DRY (Don't Repeat Yourself) coding.
Show the first image, and increase i to show the next one in the "loop"
// The images indexes holder
let i = 0;
// Set the first image (i = 0 for now)
el.style.backgroundImage = `url(${arr[i]})`;
// increase i, to prevent showing the first image twice (for the first 6 seconds).
i++;
Finally, change the background-image every 3 sec. If reaches the last index, set to the first. And repeat...
The Code:
//var images = ['background1.jpg', 'background2.jpg','background3.jpg'];
var images = ['https://www.w3schools.com/html/img_girl.jpg',
'https://www.w3schools.com/html/pic_trulli.jpg',
'https://www.w3schools.com/html/img_chania.jpg']
var main = document.querySelector("main");
const backgroundSlider = (el, arr) => {
let i = 0;
el.style.backgroundImage = `url(${arr[i]})`;
i++;
setInterval(() => {
el.style.backgroundImage = `url(${arr[i]})`;
i++;
i == arr.length ? i = 0 : '';
}, 3000);
};
backgroundSlider(main, images);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
main {
background: center / contain no-repeat;
height: 100vh;
}
<main></main>
Your code will not work because setTimeout is async. Your 3 updates are not done like 3s,6s,9s.
The three setTimeout statements are read in stepbystep order and the functions inside them are requested(in simple terms) to be run after 3s by each one of them.
They are all done after ~3s (almost 3s) delay.
So, in the end you see the last function run which has i=0 and resets to the first image.
Edit: similar solution has been posted already. This one uses jQuery.
//This will run every 3s.
setInterval(function(){
i = (i+1)%3;
$('main').css({'background-image': 'url(' + images[i] + ')',
'background-size': 'cover'
});
}, 3000);

How can I change background image in 1 second for only one time

I'm trying to change my background only one time after 1 second of loading. Then Second Image will be show.
I just want to show the first image only for 1st one second then want to show second image.
HTML
<div id="image-head" class="image-head">
</div>
CSS
.image-head {
background-image:url(background_image_1.png);
background-size: cover;
background-repeat: no-repeat;
background-position: top center;
}
JS
var images = [
"http://example.com/wp-content/uploads/2019/05/background_image_2.jpg"
]
var imageHead = document.getElementById("image-head");
var i = 1;
setInterval(function() {
imageHead.style.backgroundImage = "url(" + images[i] + ")";
i = i + 1;
if (i == images.length) {
i = 0;
}
}, 1000);
Please let me know how can I do it.
Thanks!
You need to use setTimeout instead of setInterval
And you don't even need that array
setTimeout(() => document.getElementById("image-head").style.backgroundImage = `url("http://example.com/wp-content/uploads/2019/05/background_image_2.jpg")`, 1000);
You should replace
setInterval(function() {
imageHead.style.backgroundImage = "url(" + images[i] + ")";
i = i + 1;
if (i == images.length) {
i = 0;
}
}, 1000);
by
setTimeout(function() {
imageHead.style.backgroundImage = "url(" + images[i] + ")";
i = i + 1;
if (i == images.length) {
i = 0;
}
}, 1000);
The setInterval() method, offered on the Window and Worker interfaces, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. It returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval().
The setTimeout() method of the WindowOrWorkerGlobalScope mixin (and successor to Window.setTimeout()) sets a timer which executes a function or specified piece of code once the timer expires.
See document
#DominikMatis has the correct answer, but I wanted to help clean the code up a bit.
var image = "http://example.com/wp-content/uploads/2019/05/background_image_2.jpg";
var imageHead = document.getElementById("image-head");
setTimeout(function() {
imageHead.style.backgroundImage = "url(" + image + ")";
}, 1000);
This makes more sense since you're only replacing the image once, with a single image. What you had before would work great for replacing several images at a specified time interval.

function firing multiple times when scrolling fast

First of all, I'm not very advanced at code and tend to only do this part time so please excuse all terrible/ugly code! I appreciate there are already some solutions out there but I can't seem to make any of them work with my code so would really appreciate some help!
I'm using isotope grid and trying to setup an infinite scroll. I want to load 10 images at a time when the user scrolls to the bottom by taking these images from an array and appending them to a temp div.
This is working perfectly when scrolling slowly, but as soon as you scroll quickly the function seems to fire multiple times, it gets a little glitchy and loads lots of images at once.
$(window).scroll(function() {
var scrollTop = $(window).scrollTop();
var windowHeight = $(window).height();
var docuHeight = $(document).height();
if(scrollTop + windowHeight == docuHeight){
nextTenImages = imagesData.splice(0,10);
var content = ""
for (var i = 0; i < nextTenImages.length; i++) {
content +=
"<div class='box " + nextTenImages[i]["type"] + "'" + ">" +
"<div class='box-wrapper'>" +
"<img src='" + nextTenImages[i]["src"] + "' />" +
"</div>" +
"</div>"
};
$('body').append('<div id="temp-load"><div id="grid"></div></div>');
$('#temp-load > #grid').append(content)
$('#temp-load > #grid').children().css({
opacity: 0
});
var toAdd = $('#temp-load > #grid').html();
$container.isotope('insert', $(toAdd), function(){
$container.children().css({
opacity: 1
});
$('#temp-load').remove();
});
}
});
Make a single timeout to run the callback. This may avoid the function from executing multiple times.
var timer;
function scrollEvt() {
/* scroll actions */
}
$(window).scroll(function() {
/* clear the old timeout */
clearTimeout(timer);
/* wait until 400 ms for callback */
timer = setTimeout(scrollEvt, 400);
});
Using other ways may result in problems (like comparing (window.performance || Date).now())...
Unbind that specific scroll event till your delayed operation is completed to prevent accumulating more of the event triggers which create the duplication behaviour as in your case.
var winCached = $(window),
docCached = $(document)
var currLeng = 0;
function addContent() {
dettachScrollEvent();
setTimeout(function() { //this timeout simulates the delay from the ajax post
for (var i = currLeng; i < currLeng + 100; i++)
$('div').append(i + '<br />');
currLeng = i;
console.log("called loader!");
attachScrollEvent();
}, 500);
}
function infiNLoader() {
if (winCached.scrollTop() + winCached.height() > docCached.height() - 300) {
addContent();
//alert("near bottom! Adding more dummy content for infinite scrolling");
}
}
function attachScrollEvent() {
winCached.scroll(infiNLoader);
}
function dettachScrollEvent() {
winCached.unbind('scroll', infiNLoader);
}
addContent();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>

Changing image to another on click

We are currently creating an image inside a holder (ch-item) as shown below:
<div class="ch-item ch-img-1" style="background: url(<?php echo get_template_directory_uri(); ?>/images/image1.jpg);">
If possible we would like to make this image change to another when clicked, and repeat this process six times in all, so each time it is clicked it changes to another image.
We would greatly appreciate any help. Thank you!
This is one way to do it using solely Javascript:
// Counter to keep track of which the current image is
var counter = 0;
// List of images
var images = [
'http://cdn.cutestpaw.com/wp-content/uploads/2011/11/Seemly-l.jpg',
'http://cdn.cutestpaw.com/wp-content/uploads/2011/11/Handsome-l.jpg',
// Add more images here
];
window.onload = function () {
// Get the container div
var gallery = document.getElementById('gallery');
// Run updateImage function on click
gallery.addEventListener('click', updateImage);
// Run updateImage on start
updateImage();
}
function updateImage() {
// Get the container div
var gallery = document.getElementById('gallery');
// Set background image
gallery.style.backgroundImage = 'url(' + images[counter] + ')';
// Update counter
counter++;
// Remove old class name
if (counter == 1) { // Remove last
gallery.className = gallery.className.replace(
' ch-img-' + images.length,
''
);
} else { // Remove previous
gallery.className = gallery.className.replace(
' ch-img-' + (counter - 1),
''
);
}
// Add new class name
gallery.className = gallery.className + ' ch-img-' + (counter);
// Reset counter when at the end of the images list
if (counter == images.length) {
counter = 0;
}
}
And here is a JSFiddle to try it out:
https://jsfiddle.net/0tg6up0o/14/

changing background image with a for loop

i have a table with 3 cells the middel 1 in a black image so it will look like there is a line in the middle of the screen.
now in the other cell i want to show pictures, so i tryed to do a loop that changing the images every second with by hiding the cells and then show them.
the script:
$(window).ready(function () {
//the images sits in a div with a hidden property.
var AlumniumPictures = $("#AlumnimPictureHolder").children();
var ShipozimPictures = $("#ShipozimPictureHolder").children();
//var timer = $.timer(yourfunction, 10000);
for (var i = 0; i < 10; i++) {
$(".almoniyomButtonTD").css({
"background-image": "url(" + $(AlumniumPictures[i]).attr('src') + ")"
});
$(".shipozimButtonTD").css({
"background-image": "url(" + $(ShipozimPictures[i]).attr('src') + ")"
});
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
//for some reson the code dosnt work if im not using the setInterval method.
document.setInterval(1000);
}
});
this is not working it only show me the first images and then stop.
is there a batter way to do this?
am im doing this right?
I think you might do this for the background:
$(window).ready(function () {
//the images sits in a div with a hidden property.
var AlumniumPictures = $("#AlumnimPictureHolder").children();
var ShipozimPictures = $("#ShipozimPictureHolder").children();
//var timer = $.timer(yourfunction, 10000);
time = 0;
step = 1000; // One secund
for (var i = 0; i < 10; i++) {
time+= step;
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
//for some reson the code dosnt work if im not using the setInterval method.
document.setInterval("changeBG('" + $(AlumniumPictures[i]).attr('src') + "', '.almoniyomButtonTD')", time);
document.setInterval("changeBG('" + $(AlumniumPictures[i]).attr('src') + "', '.shipozimButtonTD')", time);
}
});
function changeBG(image, obj) {
$(obj).css({
"background-image": "url(" + image + ")"
});
}
But I don't undestand what you want to do with this:
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
See the docs about setInterval. You need to tell it what code you are running.
window.setInterval(code, delay);
You aren't specifying any code for it to run! Try placing your for statement in a function and calling that.
Also, from Mozilla and MS docs setInterval seems to be on the window object, not on the document object. I don't think it will work the way you have it. I imagine if you looked in a debugger you would see an error thrown.
window.setInterval(myFunction, 1000);
function myFunction() {
for (var i = 0; i < 10; i++) {
$(".almoniyomButtonTD").css({
"background-image": "url(" + $(AlumniumPictures[i]).attr('src') + ")"
});
$(".shipozimButtonTD").css({
"background-image": "url(" + $(ShipozimPictures[i]).attr('src') + ")"
});
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
}
}

Categories