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.
Related
I have a JSFiddle that shows my code now:
https://jsfiddle.net/qtu1xgw3/2/
Basically there is an image button (pink flower) and then there are 4 images that change when the button is clicked.
Now the issue is that I want the button to hide when I get to the last image. Right now I need to click the button twice to get it to hide on the last image. But I want with the last click of the button to hide it at the same time that the last image in the gallery is shown.
One of the images is in the html part of the code, which might be what causes this issue, I think, but I'm not sure how to do this differently without breaking the code?
(random images from google used for the sake of testing)
HTML:
<div class="test">
<div class="desc">
<h2 id="title_text">test1</h2>
<p id="under_text">test2</p>
</div>
<div id="pink">
<img src="https://images.vexels.com/media/users/3/234325/isolated/lists/cba2167ec09abeeee327ffa0f994151b-detailed-flower-illustration.png" onclick="imagefun()"></div>
<div class="game">
<img src="https://images.vexels.com/media/users/3/143128/isolated/lists/2a84565e7c9642368346c7e6317fa1fa-flat-flower-illustration-doodle.png" id="getImage"></div>
</div>
CSS:
.game img {
width: 300px;
height: auto;
}
.test {
display: flex;
flex-direction: row;
}
JS:
var counter = 0,
gallery = ["https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/914750/aab494aa7cde1991d0a86cc28ec6debdbee37d7f.jpg", "https://api.assistivecards.com/cards/gardening/flowers.png", "https://i.pinimg.com/474x/7d/10/75/7d1075cf259131c942037683d2243bb0.jpg"],
imagefun = function () {
if (counter >= gallery.length) {
document.getElementById("title_text").innerHTML = "test3"; document.getElementById("under_text").innerHTML = "test4"; document.getElementById("pink").style.display = "none";
}
else{
document.getElementById("getImage").src = gallery[counter];
counter++;
}
};
I have made some change to your code. It will help you.
var counter = 0,
gallery = ["https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/914750/aab494aa7cde1991d0a86cc28ec6debdbee37d7f.jpg", "https://api.assistivecards.com/cards/gardening/flowers.png", "https://i.pinimg.com/474x/7d/10/75/7d1075cf259131c942037683d2243bb0.jpg"],
imagefun = function () {
if (counter == gallery.length -1) {
document.getElementById("getImage").src = gallery[counter];
document.getElementById("pink").style.display = "none";
}
else{
document.getElementById("getImage").src = gallery[counter];
counter++;
}
};
try this
Evaluate when the counter is equal to the size of your array if so then do the job you want
imagefun = function () {
if(counter==gallery.length)
{
document.getElementById("getImage").style.display = "none";
}
if (counter >= gallery.length) {
document.getElementById("title_text").innerHTML = "test3";
document.getElementById("under_text").innerHTML = "test4";
document.getElementById("pink").style.display = "none";
}
else{
document.getElementById("getImage").src = gallery[counter];
counter++;
}
};
The issue is that you increment your counter after the counter >= gallery.length check.
The correct solution is:
const gallery = [
"https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/914750/aab494aa7cde1991d0a86cc28ec6debdbee37d7f.jpg",
"https://api.assistivecards.com/cards/gardening/flowers.png",
"https://i.pinimg.com/474x/7d/10/75/7d1075cf259131c942037683d2243bb0.jpg",
];
let counter = 0;
document.getElementById("getImage").src = gallery[counter];
function imagefun() {
counter += 1;
document.getElementById("getImage").src = gallery[counter];
if (counter >= gallery.length - 1) {
document.getElementById("title_text").innerHTML = "test3";
document.getElementById("under_text").innerHTML = "test4";
document.getElementById("pink").style.display = "none";
}
};
I have a relatively simple demo here where I have two embed elements with the same class, and upon page load one is set to display and the other is not. I'm calling a function and setting an interval for every 5 seconds starting on page load which should toggle the display rules for the classes (only one embed element should show at a time and then they should alternate on the timer).
I have border colors on the embed elements for testing, but it seems like neither element is showing on page load once I added the second 'if' statement in the JS
What am I doing wrong
window.onload = function () {
test();
setInterval(function() {
test();
}, 5000);
}
function test(){
console.log('starting');
var all = document.getElementsByClassName('pdfEmbed');
for (var i = 0; i < all.length; i++) {
if(all[i].style.display = "none"){
all[i].style.display = "block";
}
if(all[i].style.display="block"){
all[i].style.display = "none";
}
}
}
<embed class="pdfEmbed" src="#" style="margin-top: 40px;position:absolute; display: block; left: 0; top: 0; border: 1px solid red;" width="100%" height="100%" type="application/pdf">
<embed class="pdfEmbed" src="#" style="margin-top: 40px;position:absolute; border: 1px solid black; display: none; left: 0; top: 0;" width="100%" height="100%" type="application/pdf">
Here's what's happening with the second if:
// set current child display to "block" if it is "none"
if(all[i].style.display = "none"){
all[i].style.display = "block";
}
// the check is always true, since you just set the display to "block"
if(all[i].style.display="block"){
// therefore, for all elements set display to none
all[i].style.display = "none";
}
The fix is easy: Use an else if instead of the second if. In case you only want to have the two display states "none" and "block", an else is enough.
EDIT: I just noticed a second error. You have to use comparison (== or ===) instead of assignment (=) in your if conditions. So this should be working:
if(all[i].style.display == "none") {
all[i].style.display = "block";
} else {
all[i].style.display = "none";
}
var last_index = 0;
function test() {
var e = document.querySelectorAll(".pdfEmbed");
for (var k = 0; k < e.length; k++) {
e[k].style.display = k == last_index ? "block" : "none";
}
last_index++;
if (last_index >= e.length) { last_index = 0; }
}
i have this code here for sliding images but i wanted to do the same thing for sliding text instead of images but it is not working with me when i tried it , so any one can do it for me text slider moving from left to right instead of image slider without mouse click? and thanks in advance
var mainImage = document.getElementById("mainImage");
//Create image array
var imageArray = ["Life is what happens to us while we are making other plans","Life is what happens to us while we are making other plans","Life is what happens to us while we are making other plans"];
//Set up array index
var imageIndex = 0;
function changeImage() {
mainImage.setAttribute("src",imageArray[imageIndex]);
imageIndex++;
if(imageIndex >= imageArray.length) {
imageIndex = 0;
}
}
//Create function to cycle through images
mainImage.onclick = changeImage
//Call cycle function
var intervalHandle = setInterval(changeImage,3000);
mainImage.onclick = function () {
clearInterval(intervalHandle);
}
h1 {
text-align: center;
}
#mainImage {
padding-left: 350px;
padding-top: 40px;
}
//<img id="mainImage" src="images/D.png" />
You need to use HTML DOM innerHTML Property.
Create an element with id="text" change document.getElementById("text").innerHTML
var textElement = document.getElementById("text");
//Create image array
var imageArray = ["Life is what happens to us while we are making other plans","Life is what happens to us while we are making other plans2","Life is what happens to us while we are making other plans3"];
//Set up array index
var imageIndex = 0;
function changeImage() {
textElement.innerHTML = imageArray[imageIndex]
imageIndex++;
if(imageIndex >= imageArray.length) {
imageIndex = 0;
}
}
//Create function to cycle through images
textElement.onclick = changeImage
//Call cycle function
var intervalHandle = setInterval(changeImage,3000);
textElement.onclick = function () {
clearInterval(intervalHandle);
}
h1 {
text-align: center;
}
#mainImage {
padding-left: 350px;
padding-top: 40px;
}
<p id="text"></p>
<style>
#main div {
display: none;
}
</style>
<div id="main">
<div>first</div>
<div>second</div>
<div>third</div>
</div>
<script>
var divElems = [].slice.call(document.querySelectorAll('#main div')),
main = document.querySelector('#main'), i = 0;
setInterval(function f() {
var item = divElems[i % divElems.length];
item.style.display = 'block';
i++;
}, 3000);
</script>
Can you please tell how to make within #main show up on the queue without stopping? Initially, they are hidden.
Element first, second and third should appear in sequence, every 3 seconds
First shows a block
<div>first</div>
then instead
<div>second</div>
and then
<div>third</div>
I have updated my answer again after your comment. Is this what you are looking for?
var divElems = [].slice.call(document.querySelectorAll('#main div')),
main = document.querySelector('#main'),
i = 0;
divElems[0].style.display = 'block';
setInterval(function f() {
var item = divElems[i % divElems.length];
item.style.display = 'none';
i++;
item = divElems[i % divElems.length];
item.style.display = 'block';
}, 3000);
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