Javascript slideshow won't stop - javascript

I'm creating a web page with a slide show activated by clicking a button. When I click the button the first time, I want the user to be prompted with how fast they want it to change to the next image before actually running the slide show. The next time the button is clicked, I want the slideshow to stop. Right now the first part is working, but when I click it a second time it just shows the prompt again and doesn't stop the slideshow. Can anyone tell me what I'm doing wrong? Here is my code for the given function:
function slideShow(){
var temp2 = 0;
if (temp2 == 0){
var speed = prompt("How fast would you like to the slideshow to go?");
var timerID = setInterval("clock()",speed);
temp2 = 1;
}
else if (temp2 == 1){
clearInterval(timerID);
temp2 = 0;
}
}

Move
var timerID
to outside of the function declaration.
var timerID
function slideShow(){
var temp2 = 0;
if (temp2 == 0){
var speed = prompt("How fast would you like to the slideshow to go?");
timerID = setInterval("clock()",speed);
temp2 = 1;
}
else if (temp2 == 1){
clearInterval(timerID);
temp2 = 0;
}
}
That would be the easiest way. You are basically just throwing that variable away everytime you call that function.
Just so other advice. You don't really ever want to use a string in setInterval.

Related

Javascript function is working, but when I click the second time it doesn't work anymore

I have a slider on my website page, and I wanted to create a link that redirects to a specific slide of the slider, that contains 3 slides. Because I'm a beginner in javascript, I tried the easiest way that I could think, which is to click a certain number of times according to the current slide, so for example, if my current slide position is equal to 2[0,1,2], and I want to go to position 1, I can press the next button 2 times using a Javascript click() event. It's working like a charm, but when I click for the second time, it doesn't work. I would like to know why this is happening.
const mySlide = document.querySelectorAll('.mySlides');
let counter = 1;
slidefun(counter);
let timer = setInterval(autoSlide, 8100);
function autoSlide() {
counter += 1;
slidefun(counter);
}
function plusSlides(n) {
counter += n;
slidefun(counter);
resetTimer();
}
function currentSlide(n) {
counter = n;
slidefun(counter);
resetTimer();
}
function resetTimer() {
clearInterval(timer);
timer = setInterval(autoSlide, 8100);
}
function slidefun(n) {
let i;
for(i = 0;i<mySlide.length;i++){
mySlide[i].style.display = "none";
}
if(n > mySlide.length){
counter = 1;
}
if(n < 1){
counter = mySlide.length;
}
mySlide[counter - 1].style.display = "block";
}
const slide2 = document.getElementById('slide2');
var slideButton = document.getElementById('myButton');
slideButton.addEventListener('click', openSlide);
nextButton = document.getElementsByClassName('next');
nextButton.addEventListener('click', slideSelected);
function slideSelected(){
if(currentSlide == currentSlide(0)){
nextButton.click()
}else if(currentSlide == currentSlide(2)){
nextButton.click();
nextButton.click();
}
}

JS: setInterval running as if there were multiple intervals set

So, I've been trying to figure out JS, and what better way to do so than to make a small project. It's a small trivia game, and it has a question timer I've made using setInterval. Unfortunately, after answering multiple questions, the interval's behaviour gets very weird - it runs the command twice every time. I guess it's my faulty implementation of buttonclicks?
By the way, if my code is awful I am sorry, I've been desperate to fix the issue and messed with it a lot.
function startGame(){
if (clicked === true){
return;
}
else{
$("#textPresented").html("Which anthem is this?");
$("#button").css("display", "none");
currentCountry = getRndInteger(0,8);
console.log(currentCountry);
var generatedURL = anthemnflags[currentCountry];
console.log(generatedURL);
audios.setAttribute("src", generatedURL);
audios.play();
$("#button").html("I know!");
$("#button").css("display", "block");
$("#button").click(function () {
continueManager();
});
y=10;
console.log("cleared y" + y);
x = setInterval(function(){
y = y - 1;
console.log("Counting down..." + y)
}, 1000);
console.log("INTERVAL SET");
}
}
Here is the console output:
cleared y10 flaggame.js:59:17
INTERVAL SET flaggame.js:64:17
AbortError: The fetching process for the media resource was aborted by the user agent at the user's request. flaggame.js:49
Counting down...9 flaggame.js:62:20 ---- THESE TWO ARE BEING PRINTED AT THE SAME TIME
Counting down...8 flaggame.js:62:20 ---- THESE TWO ARE BEING PRINTED AT THE SAME TIME
Counting down...7 flaggame.js:62:20
Counting down...6 flaggame.js:62:20
Counting down...5 flaggame.js:62:20
Counting down...4 flaggame.js:62:20
Counting down...3 flaggame.js:62:20
Counting down...2 flaggame.js:62:20
Counting down...1 flaggame.js:62:20
Counting down...0
THE REST OF MY CODE:
function middleGame(){
$("#button").css("display", "none");
var n = document.querySelectorAll(".flagc").length;
correctIMG = getRndInteger(0,n-1);
showFlags();
var taken = new Array();
for (var i = 0; i < n; ++i){
if (i === correctIMG){
images[i].attr("src", "res/" + flagsfiles[currentCountry]);
taken[currentCountry] = true;
}
else{
var randomFlag = getRndInteger(0, flagsfiles.length);
if (randomFlag !== currentCountry && taken[randomFlag] !== true){
images[i].attr("src", "res/" + flagsfiles[randomFlag]);
taken[randomFlag] = true;
}
}
}
$(".flagc").click(function(){
clickregister(this);
});
}
function continueManager(){
if (!clicked){
audios.pause()
clearInterval(x);
x = 0;
clicked = true;
middleGame();
return;
}
}
function clickregister(buttonClicked){
if ($(buttonClicked).attr("id") != correctIMG){
points = points - 1;
flagARR[$(buttonClicked).attr("id")].css("display", "none");
console.log("INCORRECT");
}
else{
if (y >= 0) {
var addedPoints = 1 + y;
points = points + addedPoints;
$("#points").html(points);
}
else{
points = points + 1;
}
hideFlags();
clicked = false;
startGame();
}
}
$(function(){
hideFlags();
$("#textPresented").html("When you're ready, click the button below!");
$("#button").html("I am ready!");
$("#button").click(function () {
if (!gameStarted){
gameStarted = true;
alert("STARTING GAME");
startGame();
}
});
});
Basically this is how it works:
When the "I am ready" button is clicked, startGame() is called. It plays a random tune and counts down, until the player hits the "I know" button. That button SHOULD stop the interval and start the middleGame() function, which shows 4 images, generates a random correct image and awaits input, checks if it's true, then launches startGame() again.
The first and second cycles are perfect - after the third one things get messy.
I also noticed that the "INCORRECT" log gets printed twice, why?
EDIT: here is the minimized code that has the same issue:
var x;
var gameStarted = false;
var y;
var clicked;
$(function(){
$("#button").click(function () {
if (!gameStarted){
gameStarted = true;
startGame();
}
});
});
function startGame(){
console.log("startgame()");
if (clicked === true){
return;
}
else{
console.log("!true");
$("#button").css("display", "block");
$("#button").click(function () {
continueManager();
});
y=10;
x = setInterval(function(){
y = y - 1;
console.log(y);
}, 1000);
}
}
function continueManager(){
if (!clicked){
clearInterval(x);
x = 0;
clicked = true;
middleGame();
return;
}
}
function middleGame(){
$("#button").css("display", "none");
var taken = new Array();
$(".flagc").click(function(){
clickregister(this);
});
}
function clickregister(buttonClicked){
console.log("clickgregister");
//Irrelevant code that checks the answers
clicked = false;
startGame();
}
EDIT2: It appears that my clickregister() function gets called twice, and that function then calls startGame() twice.
EDIT3: I have found the culprit! It's these lines of code:
$(".flagc").click(function(){
console.log("button" + $(this).attr("id") + "is clicked");
clickregister(this);
});
They get called twice, for the same button
I fixed it!
It turns out all I had to do was to add
$(".flagc").unbind('click');
Before the .click() function!
You need to clear the interval first then call it again. You can do that by creating a variable outside of the event listener scope and in the event listener check if the variable contains anything if yes then clear the interval of x. After clearing the interval you can reset it.
Something like this:
<button class="first" type="submit">Button</button>
const btn = document.querySelector('.first');
let x;
btn.addEventListener("click", () => {
x && clearInterval(x)
x = setInterval(() => console.log("yoo"), 500)
})
This is because if you don't clear the interval of x it will create a new one on every button press.

jQuery - Increment number every second but onclick decrease

So I am trying to increase a number every second. So far this works fine but I have an additional condition that doesn't really works and I don't know why.
What I want is that after the value hits 10 or more you can click on a div and something happens with that div but also the value decreases by 10.
My Code:
var counter = 0;
var increment = 10;
var div = document.getElementById('number');
var st = setInterval(function(){
div.innerHTML = ++counter;
if (counter >= 10){
jQuery('#red-block').click(function(e) {
jQuery(this).css('border-radius','15px');
counter = counter -10;
});
}
},1000);
#red-block {
height: 40px;
width: 40px;
background-color: #ff0000;
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="number">1</div>
<div id="red-block"></div>
The problem is that after the counter hits 10 I click, the div changes but the value jumps for example to -17 and also I can click on the div as many times as I want and every times it decreases a big amount. This should only be possible each time the counter hits 10. Anybody has a solution for me what I am doing wrong? I believe it has something to do with setInterval
It happens because you are registering a new click event handler inside your setInterval functions. Move the click registration outside of the setInterval
function.
var counter = 0;
var increment = 10;
jQuery('#red-block').click(function (e) {
if (counter >= 10) {
jQuery(this).css('border-radius', '15px');
counter = counter - 10;
}
});
var div = document.getElementById('number');
var st = setInterval(function () {
div.innerHTML = ++counter;
}, 1000);
Separate this to your setInterval function and then put your if statement inside the click function
jQuery('#red-block').click(function(e) {
if (counter >= 10){
jQuery(this).css('border-radius','15px');
counter = counter -10;
}
});
var counter = 0;
var increment = 10;
var div = document.getElementById('number');
var st = setInterval(function(){
div.innerHTML = ++counter;
},1000);
jQuery('#red-block').click(function(e) {
if (counter >= 10){
jQuery(this).css('border-radius','15px');
counter = counter -10;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="number">1</div>
<div id="red-block">Click Me</div>
The issues are:
You are registering your click event handler every time the
timer function runs, so a single click will trigger the callback
function many times. Just register it one time and within that
callback, check to see if the count should be adjusted.
Even when decreasing the counter by 10, it still increases by one.
Instead, just track the amount you are changing the count by (1 or
-10) and update the output based on the current "change by" value.
Also, since you are using jQuery, go ahead and use it (you've already taken the plunge).
Also (FYI), don't use .innnerHTML when you aren't setting any HTML, use .textContent for that. And, since you are using jQuery, you can use .text() instead of .textContent.
// Here's the jQuery way to get a reference to elements by their id's:
var $div = $('#number');
var $block = $('#red-block')
var counter = 1; // This will be the amount to change by
var count = 0; // This will be the current count at any given time
// Just set up the click event handler once, not every time the interval runs
$block.on("click", function(e) {
// But only do something if the count is right
if (count >= 10){
$(this).css('border-radius','15px');
counter = -10;
}
});
var st = setInterval(function(){
// Now, just adjust the count by the counter
count = count += counter;
$div.text(count); // <-- The jQuery way to set the text of an element
}, 1000);
#red-block {
height: 40px;
width: 40px;
background-color: #ff0000;
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="number">1</div>
<div id="red-block"></div>

Play Boostrap Popover on loop

DEMO: http://jsfiddle.net/0s730kxx/
I'm trying to open Bootstrap Popover to auto-open on loop but so far I've have manage only to auto-play once.
HTML:
<div class="container">
Hover Left |
Hover Right |
Click Me
</div>
JS:
$(document).ready(function(){
var time = 1000;
var len = $('.myclass').length;
var count = 0;
var fun = setInterval(function(){
count++;
if(count>len){
clearInterval(fun);
}
$('.p'+count).popover('show');
if(count>1){
var pre = count-1;
$('.p'+pre).popover('hide');
}
}, time);
});
Could anyone help? I want it on loop so it plays forever or atleast 10 or 20 times.
Modify javascript part of your fiddle like this:
$(document).ready(function(){
var time = 1000;
var len = $('.myclass').length;
var count = 0;
var fun = setInterval(function(){
count++;
if(count>len){
$('.p'+(count-1)).popover('hide');
count = 1;
//clearInterval(fun);
}
$('.p'+count).popover('show');
if(count>1){
var pre = count-1;
$('.p'+pre).popover('hide');
}
}, time);
});
Since you are not clearing the interval in this modified snippet, it will run forever as you expected.
Thats because you have added line
if(count>len){
clearInterval(fun);
}
After showing them 1 time count is 3 and clearInterval(fun) is called
which terminates further call to function fun().
Original comment: You can't clear the interval and expect the loop to continue! Instead of clearing set the count back to 0. But you'll also need to remember to hide the last popover.
var fun = setInterval(function(){
count++;
$('.p' + count).popover('show');
if(count > 1){
$('.p' + (count - 1)).popover('hide');
}
if(count > len){
count = 0;
}
}, time);
Here is a fiddle: http://jsfiddle.net/89gcqnfm/
Simplicity and modular arithmetic are your friends:
$(document).ready(function(){
var time = 1000;
var eles = $('.myclass');
var count = 0;
var fun = setInterval(function(){
if(eles.length < 1)
return (console.log("No elements found!")&&!1) || clearInterval(fun);
eles.eq(count%eles.length).popover('hide');
eles.eq(++count%eles.length).popover('show');
}, time);
});
https://jsfiddle.net/L2487dfy/

Preventing onclick-function to be active when in settimeout function

Im creating a memory and I almost have it all done. My remaining problem is that while in the setTimeout function,
setTimeout(function(){
for(i = 0; i < guesses.length; i++){
if(clearedPairs[i] != i){
var reset = document.getElementById(cardPosition[i]);
reset.removeAttribute("style");
}
}
score.innerHTML = parseInt(score.innerHTML,10) - 10;
resetValues();
}, 800);
If a click occurs on another card, while its waiting to turn the two open cards back over, the player will receive additional minus point, and thats not whats supposed to happen. Can anyone help?
I can post more of the code if needed.
You can use a variable to watch your state: when in the setTimeout function, set it to true. When it's finished and clicks are acceptable, set it to false. Then just use an if statement in your click handlers to check the state.
var inFunction = false;
setTimeout(function(){
inFunction = true;
for(i = 0; i < guesses.length; i++){
if(clearedPairs[i] != i){
var reset = document.getElementById(cardPosition[i]);
reset.removeAttribute("style");
}
}
score.innerHTML = parseInt(score.innerHTML,10) - 10;
resetValues();
inFunction = false;
}, 800);
Does that address your issue?

Categories

Resources