the functions in the console but in the DOM they are messed - javascript

I'm building a trivia game for a bootcamp, when i built the functions and call them they all do their work correctly, but when i call them in the correct order in the browser they messed up.
I tried some scope debugging and it starts working better but now i think the scope is fixed and still doesnt work properly
$(document).ready(function () {
$("#restartbtn").hide();//restart button starts hidden and appears when game ends
$(".game-play").on("click", function (xyz3) {//when clicked grab question and display it
grabQuestions();
$('.gameplay').empty();
cons = 0;
grabQuestions();
});
$("#restartbtn").on("click", function (xyz4) {
$('#restart').empty();
cons = 0;
grabQuestions();
});
function stopCountdown() {
clearInterval(elements.countdown);
}
function startTimer() {
elements.interval1 = setInterval(updateTimer, 1000)
}
function stopTimer() {
clearInterval(elements.interval1);
$('.timer').html('');
}
function startDelay() {
stopDelay();
elements.delay = setTimeout(grabQuestions, 4000)
}
function stopDelay() {
clearTimeout(elements.delay);
}
function updateTimer() {
elements.timmer--;
if (elements.timer < 0) {
stopTimer();
}
else {
$(".timer").html('<span class="timer">remaining time: ' + elements.timer + '</span>');
}
}
I expected it to run in order but it shows gain over and in the back runs the game

Related

Scoping issue with using clearTimeout

I am using setTimeout to run a slideshow. I want to have button to stop it. The markup is:
<h3> Modest Mouse at Fillmore in Miami <h3>
<div>
<img id="photo" src="http://the305.com/blog/wp-content/uploads/2014/05/modestmouse3.jpg" alt= "Modest Mouse at Fillmore">
<span>•</span>
<span>•</span>
<span>•</span>
</div>
<button onclick="stopShow();">Stop</button>
The JS is:
var aSlideShowPics = ["http://the305.com/blog/wp-content/uploads/2014/05/modestmouse3.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmoude7.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmouse8.jpg"
];
// Timer for SlideShow
var i = 0;
function changeSlide() {
var stopShowID;
stopShowID = window.setTimeout(function() {
newPic = aSlideShowPics[i];
$("#photo").attr("src", newPic);
i++;
if (i < aSlideShowPics.length) {
changeSlide(); // recursive call to increment i and change picture in DOM.
} else {
i = 0; // reset loop to keep slideshow going
changeSlide(); // Recursive call on loop end
}
function stopShow() {
window.clearTimeout(stopShowID);
}
}, 3000)
}
changeSlide();
I keep getting a reference error on button click of no stopShow. I've tried putting the clearTimeout function in several places in code but get same error. Perhaps a new set of eyes can see my error. Here is the jsfiddle. Thanks for any input.
Move the stopShow outside of the timeout and outside of changeSlide.
var stopShowID;
function changeSlide() {
stopShowID = window.setTimeout( function(){}, 3000);
}
function stopShow() {
if(stopShowID) {
window.clearTimeout(stopShowID);
stopShowID = null;
}
}
the stopShow() method does not exists at the window level, it only exists within the body of changeSlide(). Directly attach it to window
window.stopShow = function() ...
or pull it out of the closure
var i = 0;
var stopShowId;
function stopShow() {
window.clearTimeout(stopShowID);
}
function changeSlide() {
stopShowID = window.setTimeout(function() {
if (i >= aSlidesShowPics.length - 1)
i = 0;
var newPic = aSlideShowPics[i++];
$("#photo").attr("src", newPic);
changeSlide();
}, 3000);
}
I couldn't launch your jsfidle example, so I update the content of your code, 2 issues raised:
1- Your stopShow was undefined, so I attached it to window scope:
window.stopShow = stopShow;
2- For your ClearTimeout scope issue: your stopShowID variable was inside your function changeSlide: your stopShow was using a local copy. I basically put it as a global variable so both function could have access to it.
var aSlideShowPics = ["http://the305.com/blog/wp-content/uploads/2014/05/modestmouse3.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmoude7.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmouse8.jpg"
];
// Timer for SlideShow
var stopShowID;
var i = 0;
function stopShow() {
window.clearTimeout(stopShowID);
}
window.stopShow = stopShow;
function changeSlide() {
stopShowID = window.setTimeout(function() {
newPic = aSlideShowPics[i];
$("#photo").attr("src", newPic);
i++;
if (i < aSlideShowPics.length) {
changeSlide(); // recursive call to increment i and change picture in DOM.
} else {
i = 0; // reset loop to keep slideshow going
changeSlide(); // Recursive call on loop end
}
}, 3000)
}
changeSlide();
working jsfiddle:
http://jsfiddle.net/fLw2a4vs/44/

Change background images using setTimeout

I have 31 images and I want to display them one after another as the background of a div. I only want it to change when the user hovers over the div. My problem right now is that it just flips through all the images really fast. I am attempting to use setTimeout, but it isn't working. How can I make the delay work?
The name of the div is About_Me_Block and the images are called frame1.gif,frame2.gif ...etc
Here is my code:
function changeImg(counter) {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
}
$(document).ready(function() {
var hoverAnimate = []
"use strict";
$('#About_Me_Block').mouseenter(function() {
hoverAnimate[0] = true;
var counter = 0;
while (hoverAnimate[0]) {
console.log(counter);
setTimeout(changeImg(counter), 1000);
counter++;
if (counter === 32)
hoverAnimate[0] = false;
}
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate[0] = false;
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
setTimeout doesn't wait for the function to end, it works lile threading in other languages.
To achieve a what you want, you need to call setTimeout from the changeImg function.
var counter = 0;
$(document).ready(function() {
var hoverAnimate = []
"use strict";
$('#About_Me_Block').mouseenter(function() {
hoverAnimate[0] = true;
counter = 0;
changeImg();
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate[0] = false;
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
function changeImg() {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
counter++;
if (counter < 32 && hoverAnimate[0]) {
setTimeout(changeImg, 1000);
} else {
hoverAnimate[0] = false;
}
}
the reason they happen all at once is because while statement doesn't have delay, so all setTimeout will be set up at the same time, thus, calling changeImg all at once.
To solve this problem, you can replace setTimeout with setInterval. Instead of using while, you can just call setInterval like
var counter = 0;
var myTimer = setInterval(changeImg, 1000);
and update counter inside changeImg every time it gets called. After looping, don't forget to
clearInterval(myTimer)
It seems you need to read up on how setTimeout works. It essentially places a reminder to run a function after a given amount of milliseconds have passed. So, when you do setTimeout(changImg(counter), 1000) you are calling changImg(counter) which returns undefined. Therein producing this setTimeout(undefined, 1000) which is why it flips really fast.
So, you can use bind to allow the function to be called later with that parameter built in. Also, make sure you remove the reminders once done with clearTimeout.
function changeImg(counter) {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
}
$(document).ready(function() {
var hoverAnimate = false, id;
function loop(counter) {
if(hoverAnimate || counter < 32) {
changeImg(counter);
id = setTimeout(loop.bind(this, counter++), 1000);
}
}
$('#About_Me_Block').mouseenter(function() {
hoverAnimate = true;
id = setTimeout(loop.bind(this, 0), 1000);
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate = false;
// Don't want a reminder for a random counter to wake up.
clearTimeout(id);
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
Two methods for timers - setTimeout and SetInterval (single / repeating)
// setInterval is also in milliseconds
var intervalHandle = setInterval(<yourFuncToChangeImage>,5000);
//this handle loop and make example loop stop
yourelement.yourEvent = function() {
clearInterval(intervalHandle);
};

Javascript Countdown that loads ahref

I'm totally a beginner with JavaScript and I'm trying to make a Javascript Countdown that loads an
I'm using this code for the countdown
<script language="Javascript">
var countdown;
var countdown_number;
function countdown_init() {
countdown_number = 11;
countdown_trigger();
}
function countdown_trigger() {
if(countdown_number > 0) {
countdown_number--;
document.getElementById('countdown_text').innerHTML = countdown_number;
if(countdown_number > 0) {
countdown = setTimeout('countdown_trigger()', 1000);
}
}
}
function countdown_clear() {
clearTimeout(countdown);
}
</script>
I want to load exactly this after the count reaches 0... I am totally lost... what should I do?
It is basically a countdown that stops a music player after reaching 0. I would like to set up several countdowns with 10 mins, 15 mins, and 30 mins.
var countdown;
var countdown_number;
function countdown_init(time) {
countdown_number = time;
countdown_trigger();
}
function countdown_trigger() {
if (countdown_number > 0) {
countdown_number--;
document.getElementById('countdown_text').innerHTML = countdown_number;
setTimeout('countdown_trigger()', 1000)
} else { // when reach 0sec
stop_music()
}
}
function stop_music(){
window.location.href = "bgplayer-stop://"; //will redirect you automatically
}
Here is a simple example using mostly what you had above. This will need to be expanded a bit in order to have multiple countdowns but the general idea is here.
Fiddle: http://jsfiddle.net/zp6nfc9b/5/
HTML:
<a id="link_to_click" href="bgplayer-stop://">link</a>
<span id="countdown_text"></span>
JS:
var countdown_number;
var countdown_text = document.getElementById('countdown_text');
var link_to_click = document.getElementById('link_to_click');
function countdown_init() {
countdown_number = 11;
countdown_trigger();
}
function countdown_trigger() {
countdown_number--;
countdown_text.innerHTML = countdown_number;
if (countdown_number > 0) {
setTimeout(
function () {
countdown_trigger();
}, 1000
);
}
else {
link_to_click.click();
}
}
link_to_click.addEventListener('click',
function () {
countdown_text.innerHTML = 'link was clicked after countdown';
}
);
countdown_init();
To explain some portions a little I think overall you had the correct idea.
I only added the eventListener so you could see the link was actually being clicked and displays a message in the countdown_text for you.
You didn't need to check countdown_number more than once so I removed that if block.
Also you don't really need to clear the timeout either. It clears itself once it executes. You only really need to clear a timeout if you want to stop it before it completes but since we rely on the timeout completing in order to do the next step its not necessary.

ellipses word loading screen

What I am trying to do is make a loading screen that shows some message, and a flashing ellipses. It would look like this, but more animated:
Crunching data.
Crunching data..
Crunching data...
Crunching data.
Crunching data..
currently, I have the following code, but it crashes the site, so I'd say it's fair to assume it doesn't work:
function loader(div) {
div.append('<div id="loader"></div>');
load = div.find('#loader');
load.html('Crunching Some Data.');
numberOfPeriods = 1;
while($('#loader').length > 0) {
setTimeout(function() {
if(numberOfPeriods < 4) {
numberOfPeriods++;
for(var i=0; i<numberOfPeriods; i++) {
load.append('.');
}
} else {
load.html('Crunching Some Data.');
numberOfPeriods = 1;
}
}, 200);
}
}
how would one go about doing this?
Try something like this
function showLoader() {
var load;
load = $('<div id="loader"></div>');
$(document.body).append(load);
load.html('Crunching Some Data.');
numberOfPeriods = 1;
interval = setInterval(function(){
if(numberOfPeriods < 4)
{
load.html(load.html() + '.');
numberOfPeriods++;
}
else
{
load.html('Crunching Some Data.');
numberOfPeriods = 1;
}
}, 200);
}
function hideLoader(){
clearInterval(interval);
$('#loader').remove();
}
Don't put setTimeout inside a loop. Instead, test for the "done" condition at the top of the function called by setTimeout (test the length of #loader). If not done, use setTimeout again. If done, call a function which moves things along.

JQuery not executing within a For loop

Im a JQuery noob trying to write a simple jQuery code to get a text to blink three times. My initial code was as follows:
$("#welcome").click(function () {
var i = 1;
while (++i < 10) {
$("#welcome").fadeOut("slow", function () { $("#welcome").fadeIn("slow"); })();
}
});
But since I probably meddled in forces I could not comprehend, the above code made the text blink only once. I read up on closures and got convinced that the below code could make a change. Unfortunately, it doesnt.
$("#welcome").click(function () {
var i = 1;
while (++i < 10) {
(function (i) {
$("#welcome").fadeOut("slow", function () { $("#welcome").fadeIn("slow"); })();
})(i);
}
});
Can anyone tell me whats going on here?
You need make use of the animation queue
var $welcome = $("#welcome").click(function () {
var i = 1;
//clear previous animations
$welcome.stop(true, true);
while (++i < 10) {
$welcome.fadeOut("slow").fadeIn("slow");
}
});
Demo: Fiddle
Fading in and out takes some time, and you have to wait for your animation to be over before you can run the next one.
The provided answers solve your problem since jQuery is clever enough to bufferize your animation queue, but it may creates even more confusion for begginers, and also if you want to do something else between the fading animations, you can't rely on it anymore.
You then have to write your code on what is called an asynchronous recursive way (woah). Simply trying to understand that snippet may help you a lot with javascript general programming.
function blink(nbBlinks) {
// Only blink if the nbBlinks counter is not zero
if(nbBlinks > 0) {
$('#welcome').fadeOut('slow', function() {
// Do stuff after the fade out animation
$(this).fadeIn('slow', function() {
// Now we're done with that iteration, blink again
blink(nbBlinks-1);
})
});
}
}
// Launch our blinking function 10 times
blink(10);
This works perfectly. Demo http://jsfiddle.net/X5Qy3/
$("#welcome").click(function () {
for (var x = 0; x < 3; x += 1) {
$("#welcome").fadeOut("slow");
$("#welcome").fadeIn("slow");
}
});
Also, if you know how many times you want to do something. You should use a For Loop. While Loops are for when you don't know how many times you want it to run.
Set in queue
$("#welcome").click(function () {
var i = 1;
//clear animations whcih are running at that time
$(this).stop(true, true);
while (++i < 10) {
$(this).fadeOut("slow").fadeIn("slow");
}
});
You can not use jQuery delay function inside a looping/iteration hence you have to user closures:
$(document).ready(function(){
$(".click1").click(function () {
for (i=0;i<=10;i++) {
setTimeout(function(x) {
return function() {
$("#wrapper").fadeOut("slow", function () { $("#wrapper").fadeIn("slow"); })();
};
}(i), 1000*i);
}
});
});
<div id="wrapper"></div><div class="click1">click</div>
You can later change the count how many times you want to blink the <div>.

Categories