This question already has answers here:
Pause button for Javascript slideshow
(3 answers)
Closed 4 years ago.
When I click on some of the buttons I want the slideshow to stop working and let me see the img for 10s or 15s and then it goes back to work. I tried the setTimeout function but I think I didn't use it right. I checked some solutions here on stackoverflow for some problems that seemed like mine but nothing helped me.
Here is an executable version of my code:
https://codepen.io/Amoocris/pen/MZXQYb?send-to-phone=5555555#0
Here is my code:
var slideIndex = 0;
showSlide();
function currentSlide(n) {
showSlide(slideIndex = n);
}
function showSlide(n) {
var i;
slide = document.getElementsByClassName("mySlide");
dotz = document.getElementsByClassName("btn");
for (i = 0; i < slide.length; i++) {
slide[i].style.display = "none";
}
slideIndex++;
if (slideIndex > slide.length) {
slideIndex = 1
}
for (i = 0; i < dotz.length; i++) {
dotz[i].className = dotz[i].className.replace("active", "");
}
slide[slideIndex - 1].style.display = "block";
slide[slideIndex - 1].className += "active";
setTimeout(showSlide, 3000);
}
* {
box-sizing: border-box;
}
.img {
width: 100%;
height: 666.656px;
}
.mySlide {
max-width: 1000px;
position: relative;
margin: auto;
}
.btns {
text-align: center;
}
.btn {
cursor: pointer;
display: inline-block;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #bbb;
margin: 0 2px;
}
.active,
.btn:hover {
background-color: pink;
}
.fade {
animation-name: fade;
animation-duration: 1.5s;
}
#keyframes fade {
0% {
opacity: 0.4;
}
100% {
opacity: 1;
}
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<link rel="stylesheet" href="style.css">
<body>
<div class="slider-container">
<div class="mySlide fade">
<img src="https://images.pexels.com/photos/70497/pexels-photo-70497.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" alt="" class="img">
</div>
<div class="mySlide fade">
<img src="https://images.pexels.com/photos/1639557/pexels-photo-1639557.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" alt="" class="img">
</div>
<div class="mySlide fade">
<img src="https://images.pexels.com/photos/1639565/pexels-photo-1639565.jpeg?cs=srgb&dl=burger-close-up-delicious-1639565.jpg&fm=jpg" alt="" class="img">
</div>
<div class="btns">
<span class="btn" onclick="currentSlide(1)"></span>
<span class="btn" onclick="currentSlide(2)"></span>
<span class="btn" onclick="currentSlide(3)"></span>
</div>
</div>
<script src="script.js" charset="utf-8"></script>
</body>
</html>
You can set up a variable to keep track of slideshow’s auto play. When a button is clicked, the auto play is cancelled until after a certain time period, say 5s.
Let’s set the variable to be timer and define it at the beginning of the slideshow section in the JS file:
var timer = null;
Then in the showSlide function, in addition to calling setTimeout function like you are currently doing, you can assign the the return value of the function to timer so that you can cancel it whenever you need to:
timer = setTimeout(showSlide, 3000);
Then in the button click function you’ll write, add the following code to temporarily cancel autoplay and set to resume it after 5 seconds:
clearTimeout(timer);
timer = setTimeout(showSlide, 5000);
Hope this helps.
Related
I want to create one slide show with Array. I created the "next" button and this works good.
I tried to fix the "prv" button but I can't. What to do? I tried imgIndex--; but its not working.
let downimgs = document.querySelectorAll('.down-imgs img')
let topimg = document.querySelector('.top-img img')
let myImg = document.getElementById('mainimge')
let imgArray = ["img/3-kid.jpeg", "img/men-1.jpg", "img/woamn-1.jpeg", "img/woman-2.jpg"]
let imgIndex = 0;
downimgs.forEach(imgs => {
imgs.addEventListener('click', () => {
topimg.src = imgs.src
})
});
function next() {
myImg.setAttribute("src", imgArray[imgIndex]);
imgIndex++;
if (imgIndex >= imgArray.length) {
imgIndex = 0
}
}
// my proplem here ..
function prv() {
myImg.setAttribute("src", imgArray[imgIndex - 1]);
imgIndex--;
if (imgIndex >= imgArray.length) {
imgIndex = 3
}
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
img {
height: 300px;
}
.top-img img {
width: 100%;
object-fit: cover;
position: relative;
}
.next,
.prv {
display: inline-block;
width: 150px;
height: 150px;
left: 100%;
position: absolute;
padding: 15px;
font-size: 50px;
color: red;
cursor: pointer;
}
.next {
transform: translate(-150px, -50px);
}
.prv {
left: 0;
transform: translate(150px, -50px);
}
.down-imgs img {
width: 150px;
height: 150px;
}
.full-parent {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="s.css">
</head>
<body>
<section class="full-parent">
<figure class="top-img">
<img src="img/3-kid.jpeg" alt="" id="mainimge">
</figure>
<div class="down-imgs">
<img src="img/3-kid.jpeg" class="slide">
<img src="img/men-1.jpg" alt="" class="slide">
<img src="img/woamn-1.jpeg" alt="" class="slide">
<img src="img/woman-2.jpg" alt="" class="slide">
</div>
<span class="next" onclick="next()">❯</span>
<span class="prv" onclick="prv()">❮</span>
</section>
<script src="s.js"></script>
</body>
</html>
There is a defect in your prv function. You are decrementing imgIndex, but then checking that imgIndex is greater than or equal to the array length. Instead, you want to check that imgIndex is less than 0, then adjust accordingly. You will also want to change the order of the boundary check, otherwise you have potential to go out of bounds with imgArray[imgIndex-1].
Based on your code, I believe you want something like:
function prv(){
if (--imgIndex<0){ // if imgIndex leaves imgArray lower bound
imgIndex = imgArray.length-1; // wrap imgIndex around to the upper bound of the array
}
myImg.setAttribute("src" , imgArray[imgIndex]);
}
const firstTitle = document.querySelector(".first-title");
const secondTitle = document.querySelector(".second-title");
const firstSubtitle = document.querySelector(".first-subtitle");
const secondSubtitle = document.querySelector(".second-subtitle");
window.onload = function() {
setInterval(function() {
firstTitle.classList.add('fadeOut');
secondTitle.classList.add('fadeIn');
firstSubtitle.classList.add('fadeOut');
secondSubtitle.classList.add('fadeIn');
}, 4000);
}
h1 {
margin-bottom: 24px;
position: relative;
}
h1 span:nth-child(2) {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
p {
font-size: 20px;
line-height: 27px;
margin-bottom: 80px;
position: relative;
}
p span:nth-child(2) {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.fadeIn {
animation: fadeIn 1s linear infinite;
}
.fadeOut {
animation: fadeOut 1s linear infinite;
}
/* Fade In and Fade Out Animation */
#keyframes fadeIn {
0% {
opacity: 0;
}
50% {
opacity: 0.5
}
100% {
opacity: 1;
}
}
#keyframes fadeOut {
0% {
opacity: 1;
}
50% {
opacity: 0.5
}
100% {
opacity: 0;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Text Fading</title>
</head>
<body>
<div class="container">
<header class="header">
<section>
<h1>
<span class="first-title">Title A</span>
<span class="second-title">Title B</span>
</h1>
<p>
<span class="first-subtitle">Text A</span>
<span class="second-subtitle">Text B</span>
</p>
</section>
</header>
</div>
</body>
</html>
From my code, I have styled it in such a way that the text in the spans inside the h1 and p tags are at the same level. This is because I want a span to fade in the exact same time the other span is fading out such that it creates a temporary overlap effect. However, I am unable to do that with my present knowledge of CSS and JavaScript.
How do I continuously fade in and fade out the two different spans in h1 and p tags simultaneously in an infinite loop such that they overlap at a point before completely fading in or fading out.
solution:
let title1 = document.getElementById('first-title');
let subTitle1 = document.getElementById('first-subtitle');
let title2 = document.getElementById('second-title');
let subTitle2 = document.getElementById('second-subtitle');
// Third, create variable so is can check if this element is first element or second element
let checkTimes = true;
function hapyFade() {
setTimeout(function(){
// Sixthly,Evry time checkTimes is reverse to aprouch toggle element
if (checkTimes == true) {
// Seventh, In the first case of variapple, hide the first element and show the second
title1.style.opacity = subTitle1.style.opacity = 0;
title2.style.opacity = subTitle2.style.opacity = 1;
// Sixthly too, here reverse variable
checkTimes = false;
} else {
// Seventh too, In the second case of variapple, hide the second element and show the first
title1.style.opacity = subTitle1.style.opacity = 1;
title2.style.opacity = subTitle2.style.opacity = 0;
// Sixthly too, here reverse variable
checkTimes = true;
}
// Fifth, same a function inside setTimeOut so reabeate this each 2 second
hapyFade();
}, 2000);
}
// Fourth, I created a fuction for hide show elemnt as toggle - after 2 second
hapyFade();
h1 {
margin-bottom: 24px;
position: relative;
}
h1 span:nth-child(2) {
position: absolute;
top: 0;
left: 0;
/* Secondly, Hide the second element so that only the first element is on the square at the start of the page */
opacity: 0;
}
p {
font-size: 20px;
line-height: 27px;
margin-bottom: 80px;
position: relative;
}
p span:nth-child(2) {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
h1 span,
p span {
transition: all .5s ease-in-out;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Text Fading</title>
</head>
<body>
<div class="container">
<header class="header">
<section>
<h1>
<!-- First, here I used id so I can call it in javascript -->
<span id="first-title">Title A</span>
<span id="second-title">Title B</span>
</h1>
<p>
<span id="first-subtitle">Text A</span>
<span id="second-subtitle">Text B</span>
</p>
</section>
</header>
</div>
</body>
</html>
I have a slideshow that automatically transitions to the next picture with a timer but I want to add more functionality by pausing and by also being able to go to the next or the previous image. I am confused though on how to add those event handlers?
$(document).ready(function() {
var nextSlide = $("#slides img:first-child");
var nextCaption;
var nextSlideSource;
// the function for running the slide show
var runSlideShow = function() {
$("#caption").fadeOut(1000);
$("#slide").fadeOut(1000,
function () {
if (nextSlide.next().length == 0) {
nextSlide = $("#slides img:first-child");
}
else {
nextSlide = nextSlide.next();
}
nextSlideSource = nextSlide.attr("src");
nextCaption = nextSlide.attr("alt");
$("#slide").attr("src", nextSlideSource).fadeIn(1000);
$("#caption").text(nextCaption).fadeIn(1000);
}
)
}
// start the slide show
var timer = setInterval(runSlideShow, 3000);
})
body {
font-family: Arial, Helvetica, sans-serif;
width: 380px;
margin: 0 auto;
padding: 20px;
border: 3px solid blue;
}
h1, h2, ul, p {
margin: 0;
padding: 0;
}
h1 {
padding-bottom: .25em;
color: blue;
}
h2 {
font-size: 120%;
padding: .5em 0;
}
img {
height: 250px;
}
#slides img {
display: none;
}
#buttons {
margin-top: .5em;
text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Xochitl Menjivar</title>
<link rel="stylesheet" href="main.css">
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="slide_show.js"></script>
</head>
<body>
<main>
<h1>Fishing Slide Show</h1>
<h2 id="caption">Casting on the Upper Kings</h2>
<img id="slide" src="images/casting1.jpg" alt="">
<div id="slides">
<img src="images/casting1.jpg" alt="Casting on the Upper Kings">
<img src="images/casting2.jpg" alt="Casting on the Lower Kings">
<img src="images/catchrelease.jpg" alt="Catch and Release on the Big Horn">
<img src="images/fish.jpg" alt="Catching on the South Fork">
<img src="images/lures.jpg" alt="The Lures for Catching">
</div>
<div id="buttons">
<input type="button" id="prev" value="Previous" disabled>
<input type="button" id="play" value="Pause">
<input type="button" id="next" value="Next" disabled>
</div>
</main>
</body>
</html>
Working fiddle
For play/pause you can do this
$('#play').on('click', function(e){
e.preventDefault();
isPaused = !isPaused;
if(isPaused){
$('#play').val('Play');
window.clearInterval(timer);
} else {
$('#play').val('Pause');
timer = setInterval(runSlideShow, 3000)
}
})
Declare variable for tracking play/pause state. When it is in pause state, clear timer interval, if state is play, then set interval timer again.
Also, you could have added this flag inside runSlideShow() function
var runSlideShow = function() {
if(!isPaused){
$("#caption").fadeOut(1000);
$("#slide").fadeOut(1000,
function () {
findNextSlide()
nextSlideSource = nextSlide.attr("src");
nextCaption = nextSlide.attr("alt");
$("#slide").attr("src", nextSlideSource).fadeIn(1000);
$("#caption").text(nextCaption).fadeIn(1000);
}
)
}
}
And click event would be quite short.
$('#play').on('click', function(e){
e.preventDefault();
isPaused = !isPaused;
})
For next slide one option, would be just simply clear and start runSlideShow, which will automatically force to fetch new slide with all effects.
Show previous slide, you can use same logic, and instead finding next slide, just look for previous slide. jQuery has function .prev() which is opposite of .next()
Edit:
function findPreviousSlide(){
if (nextSlide.prev().length == 0) {
nextSlide = $("#slides img:last-child");
}
else {
nextSlide = nextSlide.prev();
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have created my own slider and now I am facing an issue with calling the auto sliding set interval function again after I used the bullet navigation. "setTimeout(autoSlide, 1000);" is not working. The code I have tried is given below. Please do get me a solution. Thank you.
<!doctype html>
<head>
<title> Custom Slider </title>
<style type="text/css">
body
{
margin: 0;
padding: 0;
}
.slide
{
float: left;
width: 960px;
height: 300px;
background-color: #000;
}
.slide h1
{
color: #fff;
}
#container
{
width: 960px;
overflow: hidden;
margin: auto;
margin-top: 100px;
}
#wrapper
{
position: relative;
right: 0px;
}
#bullets li
{
cursor: pointer;
}
</style>
</head>
<body>
<div id="container">
<div id="wrapper">
<div class="slide">
<h1>Slide 1</h1>
</div>
<div class="slide">
<h1>Slide 2</h1>
</div>
<div class="slide">
<h1>Slide 3</h1>
</div>
<div class="slide">
<h1>Slide 4</h1>
</div>
<div style="clear: both;"> </div>
</div>
</div>
<ol id="bullets">
</ol>
<script src="https://code.jquery.com/jquery-2.2.3.min.js" integrity="sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo=" crossorigin="anonymous"></script>
<script type="text/javascript">
$(document).ready(function(){
var slideWidth = $('.slide').width();
var slideLength = $('.slide').length;
var totalWidth = slideWidth * slideLength;
$('#wrapper').css('width', totalWidth);
var currentPos = $('#wrapper').position().right;
var currentIndex = 0;
var autoSlide;
function auto(){
currentIndex += 1;
if(currentIndex > slideLength - 1)
{
currentIndex = 0;
}
$('#wrapper').animate({right: currentIndex * slideWidth});
}
var autoSlide = setInterval(auto, 1000);
$('.slide').each(function(){
$('#bullets').append('<li class="bullet"> </li>');
});
$('.bullet').click(function(){
clearInterval(autoSlide);
var bulletIndex = $(this).index();
if(bulletIndex > slideLength - 1)
{
bulletIndex = 0;
}
$('#wrapper').animate({right: bulletIndex * slideWidth});
currentIndex = bulletIndex;
setTimeout(autoSlide, 1000);
});
});
</script>
</body>
setTimeout(autoSlide, 1000);
is passing an old timer handle into setInterval, which won't work. Pass the function again:
autoSlide = setTimeout(auto, 1000);
Also note that setTimeout will set up a timer that only fires once, whereas your original setInterval will set up a repeating timer, so you may have wanted setInterval there.
I'm trying to find a way to delay the final part as stated in the title.
My initial JQuery code
var debounce = false;
var elements = document.getElementsByClassName('.Menu')
$('#Option1').click(function() {
if (debounce == true) {return;}
debounce = true;
$('.Menu').each(function(index) {
anim2($(this), index * 250, function() {
if (index != elements.length) {return;}
debounce = false;
})
})
});
This produces what I want to a certain extent but due to the delays and the fact that the display becomes none, I don't get what I truly want.
GIF Representing problem : https://gyazo.com/3d8f46ec3e34dfd7b88738fc00d477e1
The initial fade in works great but on the fade out when the first button disappears the delayed buttons for the other ones shift to the left which is what I'm trying not to let happen.
I tried doing:
var debounce = false;
var isClicked = false;
var elements = document.getElementsByClassName('.Menu')
$('#Option1').click(function() {
if (debounce == true) {return;}
debounce = true;
$('.Menu').each(function(index) {
anim2($(this), index * 250, function() {
if (index != elements.length) {
if (isClicked == false) {
isClicked = true;
$('.Menu').each(function(index) {
$(this).css("display", "none");
$(this).css("opacity", "0");
})
} else {
isClicked = false;
$(this).css("display", "inline-block");
$(this).css("opacity", "1");
}
}
debounce = false;
})
})
});
But it doesn't work and creates bugs. If you need to know the anim2 function it is
function anim2(object, dt, end) {
$(object).stop().delay(dt).fadeToggle({
duration: 1000,
easing: "easeOutQuad",
quene: true,
complete: end
})
}
Just going to post the relevant parts of the LESS in case it might be the cause of it
.invisible {
background: transparent;
border: none;
}
.Hamburger {
background: #pure-white;
width: 100%;
height: 5px;
opacity: 0;
position: absolute;
.rounded
}
#Option1 {
.invisible;
position: absolute;
padding: 0px 0px 0px 0px;
top: 0px;
left: 10px;
height: 100%;
width: 40px;
#TopSpan {
.Hamburger;
top: 10px;
}
#MiddleSpan {
.Hamburger;
top: 20px;
}
#BottomSpan {
.Hamburger;
top: 30px;
}
&:active {
background: #pure-red;
}
}
I have also checked out Delay of a few seconds before display:none and Hide div after a few seconds but delay() won't work since it's an automatic effect
HTML
<!DOCTYPE html>
<html lang="en">
<head class="Setup">
<link rel="stylesheet/less" type="text/css" href="../LESS/core.less"/>
<script src="../JavaScript/less.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<script type='text/javascript' src="../JavaScript/java.js"></script>
</head>
<body class="Setup">
<div class="Design">
<div class="TopDesign">
<span id="Topbar"></span>
<span id="Minibar">
<button class="Buttons" id="Option1">
<span class="Home" id="TopSpan"></span>
<span class="Home" id="MiddleSpan"></span>
<span class="Home" id="BottomSpan"></span>
</button>
<button class="Buttons Menu" id="Sub1">
<p class="SubText">Source1</p>
</button>
<button class="Buttons Menu" id="Sub2">
<p class="SubText">Source2</p>
</button>
<button class="Buttons Menu" id="Sub3">
<p class="SubText">Source3</p>
</button>
</span>
</div>
<div class="LeftDesign">
<span id="Leftbar">
<img src="" alt="">
</span>
</div>
</div>
</body>
</html>
Here is an answer not using javascript for the animation but CSS:
https://jsfiddle.net/7a1cpu0n/
I know this isn't exactly what you wanted, but it's simpler code and you should be able to apply the concept to your project. Just use CSS transition on the elements you want to show/hide and use javascript to toggle their class.
<ul>
<li>Menu</li>
<li>link1</li>
<li>link2</li>
<li>link3</li>
</ul>
$(document).ready(function(){
$('li:first-child').click(function(){
var time = 250;
$(this).siblings().each(function(){
var el = $(this);
setTimeout( function(){
el.toggleClass('show');
}, time);
time = time+250;
});
});
});
ul li:not(:first-child){
opacity: 0;
}
ul li {
float: left;
padding: 10px;
margin: 10px;
background: #e6e6e6;
list-style: none;
transition: all 1s;
}
ul li.show {
opacity: 1;
}
This is proof of concept.