Show and hide based on time interval - javascript

I want to show and hide a series of divs based on time interval.
Show div 1 after 4 seconds, show div 2 after a further 4 seconds and so on.
The previous div being hidden, so it appears as if new information is replacing the previous and at time intervals.
I have it working to a point, it's just when I add more divs.
setInterval(function() {
$("#a").hide();
setTimeout(function() {
$("#b").fadeIn('normal');
});
}, 4000);
#b, #c {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a">1</div>
<div id="b">2</div>
<div id="c">3</div>
https://jsfiddle.net/Layt8cuy/1/
The first div needs to be there by default, and they stop with the last div with no loop back to the beginning.

Here is basic function Jsfiddle
var currentDiv = $("#a");
var nextDiv, count = 1;
var myInterval = setInterval(function() {
if (count == 5) {
clearInterval(myInterval);
} else {
count++;
currentDiv.hide();
currentDiv = currentDiv.next();
currentDiv.show();
}
}, 2000);
#b,
#c,
#d,
#e {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a">1</div>
<div id="b">2</div>
<div id="c">3</div>
<div id="d">4</div>
<div id="e">5</div>

You need a variable to track the current visible div. Also it's recommended to use a class to select all divs, otherwise you'll have to select them by tag name, which is an issue if you have other divs that shouldn't be included.
You only need setInterval() and inside it first hide all divs, then show the div with the current index, and finally increment the current index variable if it is still less that the number of divs, otherwise reset it to 0.
var current = 0;
setInterval(function() {
var divs = $(".roll").hide();
divs.eq(current).fadeIn("normal");
if (current < divs.length - 1)
current++;
else
current = 0;
}, 1000);
.roll {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a" class="roll">1</div>
<div id="b" class="roll">2</div>
<div id="c" class="roll">3</div>
To do only one loop, you need to store the ID of the setInterval() and use it in clearInterval() to stop. Here is a solution for the points in your comments:
var current = 0;
var divs = $(".roll");
var timer = setInterval(function() {
if (current < divs.length - 1) {
divs.eq(current).hide();
current++;
divs.eq(current).fadeIn("normal");
} else
clearInterval(timer);
}, 1000);
.roll {
display: none
}
#a {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a" class="roll">1</div>
<div id="b" class="roll">2</div>
<div id="c" class="roll">3</div>

a working example, with returning to first div after finish
recursive + timeout
you can use the same method for your situation:
let duration = 1000, // these are miliseconds
activeIndex = 0; // first item to activate
function activateNext() {
let boxes = $('.boxes > div');
// activate current item
boxes.addClass('hide').eq(activeIndex).removeClass('hide');
// increase activeIndex and make reset at end of collection
if (++activeIndex >= boxes.length) activeIndex = 0;
// run the function again after duration
setTimeout(function() {
activateNext(activeIndex);
}, duration)
}
// start the loop
$(window).on('load', activateNext);
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="boxes">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
Without looping back to first:
let duration = 1000, // these are miliseconds
activeIndex = 0; // first item to activate
function activateNext() {
let boxes = $('.boxes > div');
// activate current item
boxes.addClass('hide').eq(activeIndex).removeClass('hide');
// increase activeIndex and make reset at end of collection
if (++activeIndex < boxes.length) {
// run the function again after duration
setTimeout(function() {
activateNext(activeIndex);
}, duration)
}
}
// start the loop
$(window).on('load', activateNext);
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="boxes">
<div>1</div>
<div>2</div>
<div>3</div>
</div>

You might also consider pure CSS solution:
#a, #b, #c {
position: absolute;
animation: hide 4s linear forwards;
}
#b, #c {opacity: 0}
#b {
animation-delay: 4s;
}
#c {
animation-name: last;
animation-delay: 8s;
}
#keyframes hide {
0%, 99.99% {opacity: 1}
100% {opacity: 0}
}
#keyframes last {
0%, 100% {opacity: 1}
}
<div id="a">1</div>
<div id="b">2</div>
<div id="c">3</div>

Related

jQuery - element crossing another element

I have a fixed div on the page which contains a logo and as the user scrolls and this logo passes over other divs I wnat to the change the colour of the logo.
I have this working over a single div but need to it work across multiple so any help appreciated.
The WIP site can be seen here... dd.mintfresh.co.uk - if you scroll down you'll (hopefully) see the logo change from black to white as it crosses an illustrated egg. I need the same to happen when it crosses other divs further down the page.
The script so far...
jQuery(window).scroll(function(){
var fixed = jQuery("logo");
var fixed_position = jQuery("#logo").offset().top;
var fixed_height = jQuery("#logo").height();
var toCross_position = jQuery("#egg").offset().top;
var toCross_height = jQuery("#egg").height();
if (fixed_position + fixed_height < toCross_position) {
jQuery("#logo img").css({filter : "invert(100%)"});
} else if (fixed_position > toCross_position + toCross_height) {
jQuery("#logo img").css({filter : "invert(100%)"});
} else {
jQuery("#logo img").css({filter : "invert(0%)"});
}
}
);
Any help appreciated. Thanks!
you need to fire a div scroll event. you can assign
$("div1").scroll(function(){
//change the color of the div1
}
});
$("div2").scroll(function(){
//change the color of the div2
}
});
or you can assign a class to divs which you want to change the color
$(".div").scroll(function(){
//change the color of the div which you are scrolling now
}
});
You can use like this :-
$(window).scroll(function() {
var that = $(this);
$('.section').each(function() {
var s = $(this);
if (that.scrollTop() >= s.position().top) {
if(s.hasClass('active')) {
$('.logo').addClass('invert');
} else {
$('.logo').removeClass('invert');
}
}
});
});
body {
padding: 0;
margin: 0;
}
div {
background: #f00;
height: 400px;
}
.logo {
position: fixed;
top: 0;
left: 0;
width: 100px;
}
.logo.invert {
filter: invert(100%);
}
div:nth-child(even) {
background: #ff0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://dd.mintfresh.co.uk/wp-content/uploads/2018/06/DD_logo.svg" class="logo" />
<div id="page1" class="section"></div>
<div id="page2" class="section active"></div>
<div id="page3" class="section"></div>
<div id="page4" class="section active"></div>
<div id="page5" class="section"></div>
As your site code you can do like this :
$(window).scroll(function() {
var that = $(this);
$('#content > section').each(function() {
var s = $(this);
if (that.scrollTop() >= s.position().top) {
if(s.hasClass('black')) {
$('#logo img').css({filter: 'invert(0%)'});
} else {
$('#logo img').css({filter: 'invert(100%)'});
}
}
});
});

jQuery - change class with timer

I have a CSS slider that I'm using with a bit of jQuery to change the class of the list item on click. I would also like to have the slider on a timer so every 5s it auto executes the removeClass of the selected list item and adds "selected" class to the next list item in the list if there is no user interaction.
At the same time as changing the class on the li element it needs to change the #slide_images transform to what it needs to be (0px,1100px,2200px,3300px or 4400px) etc.
If it does have user interaction via them selecting a link for a slide then the timer should stop until page reload.
Here is the HTML:
<div id="slide_container">
<div style="transform: translateX(0px);" id="slide_images">
<div class="slide1">
<img src="http://example.com/1.jpg">
<div class="slide-content1">
slide1content
</div>
</div>
<div class="slide2">
<img src="http://example.com/2.jpg">
<div class="slide-content2">
slide1content
</div>
</div>
<div class="slide3">
<img src="http://example.com/3.jpg">
<div class="slide-content3">
slide1content
</div>
</div>
</div>
</div>
Here is the CSS:
.slide-content1,.slide-content2,.slide-content3,.slide-content4,.slide-content5{position:absolute;top:20px;left:0;padding:110px 0 0;width:1100px;color:#fff}
.slide-content2{left:1100px}
.slide-content3{left:2200px}
.slide-content4{left:3300px}
.slide-content5{left:4400px}
#slide_container{width:1100px;height:580px;overflow:hidden;margin:0 auto}
#slide_images{width:5500px;-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out}
#slide_images img{padding:0;margin:0;float:left;border:none}
Here is the script:
jQuery(document).ready(function($) {
$(document).ready(function() {
$('.slidenav').on('click', 'li', function(){
$("#slide_images").css("transform","translateX("+$(this).index() * -1100+"px)");
$(".slidenav li").removeClass("selected");
$(this).addClass("selected");
});
});
});
Thanks for any help :).
I have an example with a working rotator. It will rotate every 5 seconds when there is no user interaction. When you click on a item, the timer resets to 0 and continues after 5 seconds with rotation.
HTML:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script src="script.js"></script>
</head>
<body>
<ul class="slidenav">
<li>slide1</li>
<li>slide2</li>
<li>slide3</li>
</ul>
</body>
</html>
CSS:
ul.slidenav li {
color: #000;
}
ul.slidenav li.selected {
color: red;
}
JS:
$(document).ready(function() {
var slides = $(".slidenav li");
//Init slide 1
slideTo(slides[0]);
var slideIndex = 0;
var slideTime = animate();
$(".slidenav li").click(function() {
//Reset the interval to 0 and start it again
clearInterval(slideTime);
slideTime = animate();
var selectedIndex = $(this).index();
var slide = slides[selectedIndex];
slideTo(slide);
});
function slideTo(slide) {
$(".slidenav li").removeClass("selected");
$(slide).addClass("selected");
slideIndex = jQuery(slide).index();
}
function animate() {
return setInterval(function() {
var slide = slides[slideIndex];
slideTo(slide)
slideIndex++;
if (slideIndex == slides.length) {
slideIndex = 0;
}
}, 5000);
}
});
Plunker: https://plnkr.co/edit/ah1CTexSjnROAEPMAitk?p=preview
To execute something with a delay, you can use setTimeout().
You can use a delayTime variable and then modify it on user click event.
A quick approach to the solution would be
var delayTime = 5000; // milliseconds
$(function() {
$('.slidenav').click(function () {
setTimeout(function () {
$('.slidenav li').removeClass('newClass');
}, delayTime);
});
$('.clickedLink').click(function () {
delayTime = 0;
});
});
Notice, I also shortened the code a little bit: $(ready) and .on('click')
Take a look at this codesnippet.
$(document).ready(function(){
$(".slider li:first-child").addClass("active");
setTimeout(autoAddClass, 1000);
});
function autoAddClass(){
var next = $(".active").removeClass("active").next();
if(next.length)
$(next).addClass('active');
else
$('.slider li:first-child').addClass('active');
setTimeout(autoAddClass, 1000);
}
You should start by setting an interval, and once your user does his interaction, you can clear that interval using clearInterval. Here is a pseudo code:
var interval = setInteval(function(){
// do whatever here...
}, 5000);
$('yourSelector').click(function(){
clearInterval(interval);
// do whatever....
});

disable and enable click events with a counter and transition effects

I have the following lines of code in my web page - demo/example.
HTML:
<button class="wrong-answer" onclick="showResult(this)">42</button>
<button class="right-answer" onclick="showResult(this)">43</button>
<p id="answer" class="answer-display-hidden">answer</p>
<div class="incorrect">
<span>Incorrect:</span>
<p>0</p>
</div>
<div class="correct">
<span>Correct:</span>
<p>0</p>
</div>
CSS:
.answer-display-visible {
visibility: visible;
opacity: 1;
transition: opacity 1s linear;
}
.answer-display-hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 1s, opacity 1s linear;
}
.incorrect, .correct {float: left; padding-right: 20px}
JS:
var incorrectCalls = 0;
var correctCalls = 0;
function showResult(b) {
var res = document.getElementById('answer');
if (b.classList.contains('right-answer')) {
res.innerHTML = '<span class="right">right</span>';
correctCalls++;
var cor = $('.correct > p:first');
cor[0].innerHTML = correctCalls;
}
else {
res.innerHTML = '<span class="wrong">wrong</span>';
incorrectCalls++;
var incor = $('.incorrect > p:first');
incor[0].innerHTML = incorrectCalls;
}
res.classList.remove("answer-display-hidden");
res.classList.add("answer-display-visible");
setTimeout(function() {
res.classList.add("answer-display-hidden");
}, 2000);
}
How can I de-activate the right-answer counter during the fade-in and wait effect on the text, and then re-activate afterwards? This is so that the user can't manipulate the counter (click on the button quickly before the text is displayed).
You can use setTimeout function when button clicked.
Live Demo
Code Block:
function showResult(b) {
.
.
.
$(".right-answer").prop("disabled", true);
$(".wrong-answer").prop("disabled", true);
setTimeout(function() {
$(".right-answer").prop("disabled", false);
$(".wrong-answer").prop("disabled", false);
}, 2600);
}
This is my solution
WORKING DEMO
Removed CSS code and following is the jQuery code.
$(document).ready(function(){
$(".wrong-answer").click(function(){
$(".right-answer").attr("disabled","disabled");
$("#answer").text("WRONG").fadeIn(5000,function(){
$(this).fadeOut(5000,function(){
$(".right-answer").removeAttr("disabled");
});
})
});
});

Fade In/Fade Out Through Unknown Amount of Divs, With Delay Between

I've search around and tried my best, but could not find out how to achieve the following:
Loop through an unknown amount of divs
Have some sort of animation (maybe just a simple width growth of 110%)
Each Div fades in/fades out
Delay in between the final div fading out and the first div fading in again
My Current code is as follows
JS Fiddle Link - Example
HTML
<div class="container">
<div class="popup">Popup 1</div>
<div class="popup r">Popup 2</div>
<div class="popup b">Popup 3</div>
<div class="popup g">Popup 4</div>
<div class="popup y">Popup 5</div>
</div>
CSS
.popup {
display: none;
width: 400px;
height: 80px;
background: #000;
color: #fff;
line-height: 80px;
text-align: center;
}
.r{background:red}
.b{background:blue}
.g{background:green}
.y{background:yellow}
jQuery
var popups = $('.popup');
var i = 0;
function step() {
if (i >= popups.length)
i = 0;
$(popups[i]).fadeToggle(300);
i++;
}
setInterval(step, 2000);
As you can see, my divs don't fade out until all are shown, this is not desired.
You can chain together animations with a delay between:
function next() {
if (i >= popups.length)
i = 0;
popups.eq(i).fadeIn(300).delay(2500).fadeOut(300).delay(1000).queue(function(){
next();
$(this).dequeue();
});
i++;
}
next()
(note: I have used popups.eq(i) which is the same as $(popups[i]))
Live example: http://jsfiddle.net/3ujb7k4L/7/
Something like this?
var popups = $('.popup');
var i = 0;
function fadeOutLater(popup) {
setInterval(function() {
popup.fadeOut(500);
}, 5000);
}
function step() {
var popup;
if (i >= popups.length)
i = 0;
popup = $(popups[i]);
popup.fadeIn(300, fadeOutLater(popup));
i++;
}
setInterval(step, 2000);
To create a longer pause between hiding the last element and showing the first element again you could skip one fadeIn/fadeOut cycle on resetting the counter:
var popups = $('.popup');
var i = 0;
function step() {
if (i >= popups.length) {
i = 0;
} else {
$(popups[i]).delay(300).fadeIn(300).delay(200).fadeOut(300).delay(200);
i++;
}
}
setInterval(step, 2000);
Like here: http://jsfiddle.net/r72qpher/

Javascript countdown Issue. Want to clearInterval every click on button

Fiddle : http://jsfiddle.net/gLLvux07/
I am creating a countdown using javascript. its working fine when i click the button.
The issue is,
if I click the button when countdown running, it will not start from 0.
I am trying to clear interval in the beginning of function, but not working.
HTML :
<style>
.container {
width:50px;
height:25px;
overflow:hidden;
margin-top:100px;
margin-left:100px;
border:2px solid #ddd;
}
.count {
-webkit-transition: all 1;
-moz-transition: all 1;
transition: all 1;
}
</style>
<div class="container">
<div class="count">
<div>0</div>
</div>
</div>
<div style="text-align:center">
<input type="button" onclick="countdown();" value="Click Me" />
</div>
Javascript Code :
function countdown() {
clearInterval();
$(".container .count").html("<div>0</div>")
for(i=1;i<25;i++){
$(".container .count").append("<div>"+i+"</div>");
}
var count1 = 0;
var topmove = -10;
counting = setInterval(function(){
$(".container .count").css({'-webkit-transform': 'translateY('+topmove+'px)'});
count1 = count1+1;
topmove = topmove-10;
if(count1>40) {
clearInterval(counting);
}
},100);
}
Just define counting in global scope & do clearInterval(counting); in starting of function itself. You are not passing parameters to clearInterval.
DEMO
clearInterval requires a parameter telling the script which countdown to stop. Try something like this:
var counting;
function countdown() {
if (typeof counting === 'number') clearInterval(counting);
$(".container .count").html("<div>0</div>")
for(i=1;i<25;i++)
$(".container .count").append("<div>"+i+"</div>");
var count1 = 0,
topmove = -10;
counting = setInterval(function(){
$(".container .count").css({
'-webkit-transform': 'translateY('+topmove+'px)'
});
count1 = count1+1;
topmove = topmove-10;
if (count1>40){
clearInterval(counting);
}
},100);
}

Categories

Resources