I’m a complete jquery newb and I want to create 5 classes(.button1 - .button5) with a timer which toggles the next classes :hover or :active state every 4000ms on a continuous loop. I also want the ability for the timer to halt and continue if another one of the classes is hovered on by the user. Does anyone know of a good starting point or a thread with a similar solution?
I’ve attached a diagram.
CSS
.wrapper { width:100%; margin:0 auto; background:#f3f3f3; }
#buttonblock { display:block; }
.button1, .button2, .button3, .button4, .button5 { display:inline-block; margin:0 5px; height:50px; width:50px; border-radius:25px; background:#3cc8dd; }
.button1:hover, .button2:hover, .button3:hover, .button4:hover, .button5:hover{ background:#fbc040; }
HTML
<div class="wrapper">
<div id="buttonblock">
<div class="button1"></div>
<div class="button2"></div>
<div class="button3"></div>
<div class="button4"></div>
<div class="button5"></div>
</div>
</div>
you can simply loop over the array of objects, for example
var $block = $('#buttonblock div');
for (var n=0; n<$block.length; n++)
{
var domELM = $block[n]; // you can do $(domELM) to create a jquery of the dom
// do stuff here, set interval or whatever it is you wish to do.
if(n == $block.elngth)
n=0; //resets the loop
}
HTML
<div class="wrapper">
<div id="buttonblock">
<div class="button button1"></div>
<div class="button button2"></div>
<div class="button button3"></div>
<div class="button button4"></div>
<div class="button button5"></div>
</div>
css
.hover {
background:#fbc040;
}
js
var counter = 1;
var timer;
$(document).ready(function () {
startTimer();
$('.button').mouseenter(function () {
$('.hover').removeClass('hover');
clearInterval(timer);
});
$('.button').mouseleave(function () {
startTimer();
});
});
function startTimer() {
timer = setInterval(function () {
counter = (counter > 5) ? 1 : counter;
$('.hover').removeClass('hover');
$('.button' + counter).addClass('hover');
counter++;
}, 4000);
}
JSFiddle
Try this
var divs = $('#buttonblock').children('div'),
number = divs.length,
currentIndex = 0,
intervalLength = 2000;
function setTimer() {
divs.removeClass('hover');
divs.eq(currentIndex).addClass('hover');
currentIndex++;
if (currentIndex == number) {
currentIndex = 0;
}
}
setTimer();
var timer = setInterval(setTimer, intervalLength);
divs.mouseenter(function () {
clearInterval(timer);
divs.removeClass('hover');
var div = $(this);
div.addClass('hover');
currentIndex = divs.index(div);
}).mouseleave(function () {
timer = setInterval(setTimer, intervalLength);
});
Example - setInterval
or using setTimeout
Related
(?) I want to change my class name 'box' from opacity '0' to opacity '1.0' like an animation or fade in every sec 1000ms, 2000ms. 3000ms,
(X) But I don't want to do something like this code but appears fade in like this Code on jsfiddle and not fade in at the same time like this Code on jsfiddle.
var DivB = document.getElementsByClassName("box");
setTimeout(function(){DivB[0].style.opacity = "1"}, 1000);
setTimeout(function(){DivB[1].style.opacity = "1"}, 2000);
setTimeout(function(){DivB[2].style.opacity = "1"}, 3000);
(/) I want to make It appears with the delays 1000,2000,3000 with javascript look shorter like using var 'i' to javascript like this .. Code on jsfiddle.
var DivB = document.getElementsByClassName("box");
var i;
function myFade(){
for (var i=0; i<DivB.length; i++){
setTimeout(function(){DivR[i].style.opacity="1"}, i*1000)}
}
myFade();
You're looking for setInterval
var DivB = document.getElementsByClassName("box");
var divIndex = 0;
var interval = setInterval(() => {
DivB[divIndex].style.opacity = "1";
divIndex++;
if (divIndex === divB.length - 1) clearInterval(interval);
} , 1000)
Basically, this will fire every one second, setting the opacity of divB[divIndex] to '1'. divIndex itself increments every interval as well. After all the DivB elements are processed, the interval will be cleared.
You can add transition: all 1s; to the box CSS from one of the code examples you posted:
var DivB = document.getElementsByClassName("box");
setTimeout(function(){DivB[0].style.opacity = "1"}, 1000);
setTimeout(function(){DivB[1].style.opacity = "1"}, 2000);
setTimeout(function(){DivB[2].style.opacity = "1"}, 3000);
.box { display:inline-block; position:relative; opacity:0;
transition: all 1s;}
<div class='box'>1</div><br/>
<div class='box'>2</div><br/>
<div class='box'>3</div><br/>
You can do this :
var DivB = document.getElementsByClassName("box");
function myFade() {
for (let i = 0; i < DivB.length; i++) {
setTimeout(() => {
DivB[i].style.opacity = "1"
}, i * 1000)
}
}
myFade();
.box {
display: inline-block;
position: relative;
opacity: 0;
}
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
I would suggest you to read the difference between var and let specially when using in loops with setTimeout and setInterval
Hope this helps !
Try it:
function fadeElementsProgressive(className, timePerElement = 1000) {
const divs = document.getElementsByClassName(className);
for(let i = 0; i < divs.length; i++) {
setTimeout(() => {
divs[i].style.opacity = 1;
}, i * timePerElement)
}
}
fadeElementsProgressive('box');
.box { display:inline-block; position:relative; opacity:0; }
<div class='box'>1</div><br/>
<div class='box'>2</div><br/>
<div class='box'>3</div><br/>
This will create a function that get a class name and execute a fade.
I am working on a slideshow for the homepage of my website. It works, automatically shifting throughout 1-3, but the onclick functions are having some troubles. Every single one of the buttons bring me to my first slide, not the second or the third, just the first. Any help is appreciated, please and thanks!
document.getElementById("left").style.opacity =1;
var currentSlide = 2;
var myVar = setInterval(changeSlide, 5000);
function changeSlide() {
if (currentSlide == 1) {
currentSlide++;
document.getElementById("slide1IMG").src = 'http://theskindealer.com/img/slide1.png';
document.getElementById("left").style.opacity =1;
document.getElementById("right").style.opacity =.5;
} else if (currentSlide == 2) {
currentSlide++;
document.getElementById("slide1IMG").src = 'http://theskindealer.com/img/slide2.png';
document.getElementById("middle").style.opacity =1;
document.getElementById("left").style.opacity =.5;
} else {
--currentSlide;
--currentSlide;
document.getElementById("slide1IMG").src = 'http://theskindealer.com/img/slide3.png';
document.getElementById("right").style.opacity =1;
document.getElementById("middle").style.opacity =.5;
}
}
function firstSlide() {
currentSlide = 1;
myVar = setInterval(changeSlide, 5000);
}
function secondSlide() {
currentSlide = 2;
myVar = setInterval(changeSlide, 5000);
}
function thirdSlide() {
currentSlide = 3;
myVar = setInterval(changeSlide, 5000);
}
<div id="slideshow">
<div id="slide1">
<img src="/img/slide1.png" alt="" style="width:100%;height:100%;position:absolute;" id="slide1IMG">
</div>
<div id="selectors">
<a href="" onclick="firstSlide()">
<div id="left">
</div>
</a>
<a href="" onclick="secondSlide()">
<div id="middle">
</div>
</a>
<a href="" onclick="thirdSlide()">
<div id="right">
</div>
</a>
</div>
</div>
You are using links <a> tags, to handle your clicks, the page is reloading every time you click on one of them, on page reload, it will display the first slide. That is the expected behavior of href="".
The easiest solution is to change your <a> tags for <button> tags, though you could also catch the event and use event.preventDefault() to stop the page from reloading.
<button onclick="firstSlide()">
...
</button>
<button onclick="secondSlide()">
...
</button>
<button onclick="thirdSlide()">
...
</button>
Once you stop navigating away from the page, your code will be setting a new interval every time you handle the click, to avoid that, you could use a setTimeout() at the end of changeSlide(), instead of an interval, or clear the interval on your click handlers
function firstSlide() {
// Change the current slide
currentSlide = 1;
changeSlide();
// Reset the interval
clearInterval(myVar);
myVar = setInterval(changeSlide, 5000);
}
I would probaly rename myVar to something that makes it clear that it is the interval, like refreshSlideInterval.
You could also change the conditionals inside changeSlide to use strict comparisons
if (currentSlide == 1) {...}
to
if (currentSlide === 1) {...}
Since you know that you are working with integers.
Example snippet
const content = document.getElementById("content");
let currentSlide = 2;
let slideCountDown = setTimeout(changeSlide, 3000);
function changeSlide() {
// Clear the timeout
clearTimeout(slideCountDown);
if (currentSlide === 1) {
currentSlide = 2;
content.innerText = 1;
} else if (currentSlide === 2) {
currentSlide = 3;
content.innerText = 2;
} else {
currentSlide = 1;
content.innerText = 3;
}
// Reset the timeout
slideCountDown = setTimeout(changeSlide, 3000);
}
function firstSlide() {
currentSlide = 1;
changeSlide();
}
function secondSlide() {
currentSlide = 2;
changeSlide();
}
function thirdSlide() {
currentSlide = 3;
changeSlide();
}
#container {
display: flex;
flex-direction: column;
align-items: center;
}
#content {
font-size: 5rem;
padding: 2rem;
}
#buttons {
display: flex;
flex-direction: row;
}
<div id="container">
<div id="content">1</div>
<div id="buttons">
<button onclick="firstSlide()">
First
</button>
<button onclick="secondSlide()">
Second
</button>
<button onclick="thirdSlide()">
Third
</button>
</div>
</div>
The setInterval at each select function are not necessary.
According to the changeSlide function, change the currentSlide as follow.
function firstSlide() {
currentSlide = 3;
}
function secondSlide() {
currentSlide = 1;
}
function thirdSlide() {
currentSlide = 2;
}
check this (run the snippet below ) i fixed some syntax errors :
document.getElementById("left").style.opacity =1;
var currentSlide = 1;
var myVar = setInterval(function(){
return changeSlide()
}
,1000);
function changeSlide() {
if (currentSlide == 1) {
currentSlide++;
document.getElementById("slide1IMG").src = 'https://upload.wikimedia.org/wikipedia/commons/e/e1/FullMoon2010.jpg';
document.getElementById("left").style.opacity =1;
document.getElementById("right").style.opacity =.5;
} else if (currentSlide == 2) {
currentSlide++;
document.getElementById("slide1IMG").src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Stellar_%289460796504%29.jpg/1024px-Stellar_%289460796504%29.jpg';
document.getElementById("middle").style.opacity =1;
document.getElementById("left").style.opacity =.5;
} else if(currentSlide==3){
currentSlide = 1;
document.getElementById("slide1IMG").src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Pillars_of_creation_2014_HST_WFC3-UVIS_full-res_denoised.jpg/1024px-Pillars_of_creation_2014_HST_WFC3-UVIS_full-res_denoised.jpg';
document.getElementById("right").style.opacity =1;
document.getElementById("middle").style.opacity =.5;
}
}
function firstSlide() {
currentSlide = 1;
clearInterval(myVar)
myVar = setInterval(changeSlide(), 1000);
}
function secondSlide() {
currentSlide = 2;
clearInterval(myVar)
myVar = setInterval(changeSlide(), 1000);
}
function thirdSlide() {
currentSlide = 3;
clearInterval(myVar)
myVar = setInterval(changeSlide(), 1000);
}
<div id="slideshow">
<div id="slide1">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Stellar_%289460796504%29.jpg/1024px-Stellar_%289460796504%29.jpg" alt="" style="width:100%;height:100%;position:absolute;" id="slide1IMG">
</div>
<div id="selectors">
<a href="" onclick="firstSlide()">
<div id="left">
</div>
</a>
<a href="" onclick="secondSlide()">
<div id="middle">
</div>
</a>
<a href="" onclick="thirdSlide()">
<div id="right">
</div>
</a>
</div>
</div>
How can I stop setInterval and then resume from the same place?
Example:
start ---> 1,2,3,4,5 .... ---> stop ---> start ---> 6,7,8 ...
index.html
<div onclick=start()>start</div>
<div onclick=stop()>stop</div>
index.js
let refreshInterval = null;
start() {
var i = 0;
refreshInterval = setInterval(function() {
console.log(i);
i++;
}, 1000);
}
stop() {
???????
}
You need a global variable i and for stopping a clearInterval.
function start() {
if (refreshInterval !== undefined) return; // prevent more than one interval
refreshInterval = setInterval(function() {
console.log(i);
i++;
}, 1000);
}
function stop() {
clearInterval(refreshInterval);
refreshInterval = undefined;
}
var refreshInterval,
i = 0;
<div onclick="start()">start</div>
<div onclick="stop()">stop</div>
You can keep the count variable in outer scope so it will not reset everytime you run start function
let refreshInterval = null;
let count = 0
function start() {
refreshInterval = setInterval(function() {
document.getElementById('value').innerText = count
count++;
}, 1000);
document.getElementById('start').disabled=true
}
function stop() {
clearInterval(refreshInterval)
document.getElementById('start').disabled=false
}
#counter{
padding: 0.25rem;
font-size: 1.25rem;
border: 1px solid black;
margin-bottom: 1rem;
}
<div id='counter'><span>counter:</span>
<span id='value'/>0</div>
<button onclick=start() id='start'>start</button>
<button onclick=stop() id='stop'>stop</button>
My slider is allowing for content to go forwards and backwards when the Next/Previous links are clicked. When I switch the contentType to 'div' it only shows content in slides 1 and 3. Could someone please explain why the counter is not incrementing properly? Is there a more effecient way to do this? I have included my code below as well as a working example. The purpose of this script is to allow for images or content to be displayed in a slide. Any help is much appreciated!
$(document).ready(function() {
// VARIABLE DECLARATIONS
var $el = $('#showcase');
var $leftArrow = $('#left_arrow');
var $rightArrow = $('#right_arrow');
var contentType = $('div'); // change to img and reverse comment out HTML code
var slideCount = $el.children().length;
var slideNum = 1;
var $load = $el.find(contentType)[0];
// PRELOADS SLIDE WITH CORRECT SETTINGS
$load.className = 'active';
$leftArrow.addClass("disabled");
// CHECKS FOR FIRST AND LAST INDEX
function checkSlide() {
if (slideNum == 1) {
$leftArrow.addClass('disabled');
} else {
$leftArrow.removeClass('disabled');
}
if (slideNum == slideCount) {
$rightArrow.addClass('disabled');
} else {
$rightArrow.removeClass('disabled');
}
}
// NAVIGATIONAL LOGIC FOR PREVIOUS/NEXT BUTTONS
$leftArrow.click(function() {
if (slideNum > 1) {
var counter = $(".active").index();
counter--;
$('.active').addClass('slide');
$('.active').removeClass('active');
contentType.eq(counter).addClass('active');
slideNum--;
checkSlide();
console.log('slideNum: ' + slideNum);
console.log('counter: ' + counter);
}
})
$rightArrow.click(function() {
if (slideNum < slideCount) {
var counter = $(".active").index();
counter++;
$('.active').addClass('slide');
$(".active").removeClass('active');
contentType.eq(counter).addClass('active');
slideNum++;
checkSlide();
console.log('slideNum: ' + slideNum);
console.log('counter: ' + counter);
}
})
});
img {
width: 160px;
}
a {
color: blue;
}
.disabled {
color: red !important;
}
.slide {
display: none;
}
.active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- <div id="showcase">
<img class="slide" src="https://picsum.photos/458/354" />
<img class="slide" src="https://picsum.photos/458/354/?image=306" />
<img class="slide" src="https://picsum.photos/458/354/?image=626" />
</div>
« Previous
Next » -->
<div id="showcase">
<div class="slide">Page 1 content</div>
<div class="slide">Page 2 content</div>
<div class="slide">Page 3 content</div>
</div>
« Previous
Next »
The issue is that your "contentType" var, which matches divs, also matches the "showcase" div, so you are getting 4 in your list, not 3 as you expect. In your left/right arrow click handlers, replace:
contentType.eq(counter).addClass('active');
with:
$el.find(contentType).eq(counter).addClass('active');
I am creating a simple image slide with JavaScript, but when I loop through all the images, I can not reset the loop:
var images = document.querySelectorAll(".slide-img");
var index = 0;
var time = 1000;
function reset(){
for(var i = 0; i <= 3; i++){
images[i].style.display = 'none';
images[0].style.display = 'block';
}
}
reset();
var looper = setInterval(function(){
index++;
images[index].style.display = 'block';
if(index == 3){
index = 0;
images[index].style.display = 'block';
//or calling reset() again.
}
}, 1000);
After setting all the image display:noneexcept the first one, I tried calling setInterval for looping all my images, but problem occurs when the index is 3. I am calling the reset() function and it is not working?
Your code has a few problems.
The code inside the if statement doesn't reset all the images to hidden. So you would need to call reset function instead
Your reset function doesn't reset the index.
You should set index 0 to block once, and then loop through the rest instead of setting index 0 to block in each iteration.
Because you reset when index == 3, you will never see the last image. You should reset on the following iteration to ensure that each image is visible for one second.
See my example below.
var images = document.querySelectorAll(".slide-img");
var index = 0;
var time = 1000;
function reset(){
index = 0;
images[0].style.display = 'block';
for(var i = 1; i < images.length; i++){
images[i].style.display = 'none';
}
}
reset();
setInterval(function(){
index++;
if(index >= images.length){
reset();
} else {
images[index].style.display = 'block';
}
}, 1000);
.container {
display: flex;
}
.slide-img {
width: 100px;
height: 100px;
}
<div class="container">
<div class="slide-img" style="background: red"></div>
<div class="slide-img" style="background: blue"></div>
<div class="slide-img" style="background: green"></div>
<div class="slide-img" style="background: purple"></div>
</div>
If you have other question on why my code is different than yours, ask in the comments. But I think the code should be clear and understandable.