hi i am confused with the below code
JSfiddle link
for (var i=6;i>=0;i--)
{
setTimeout((function(i)
{
$("div").delay(4000).html(i);
alert(i); //if commented unable to see the countdown
})
(i),4000);
//alert(1);
}
I am not able to get the count down timer.. whats wrong.. when "alert" is commented unable to see the count down numbers.
Please somebody explain how the above code works.. Post some correct code
.delay() only works for jQuery animation methods, not general jQuery methods such as .html()
All of your timeouts are getting fired at once - there's nothing to space them out.
The net result is that (without an alert) every iteration through the loop runs immediately, leaving the div containing 0 having invisibly (and very briefly) contained the other numbers from the previous iterations.
Try this, instead:
function counter($el, n) {
(function loop() {
$el.html(n);
if (n--) {
setTimeout(loop, 1000);
}
})();
}
counter($('div'), 6);
See http://jsfiddle.net/alnitak/t3AA8/
Do not use alert, because alert will stop everything. Use console.log
Related
Morning all,
Definitely a novice question here, this is my first real JS project - so apologies in advance for the clunky code.
The following functions are being used to show the light sequence for a "simon" game. The code seems to work fine initially, as I've tested multiple lengths of array, however on exiting the loop I get the following error:
Uncaught TypeError: Cannot read property 'setAttribute' of null
at show (script.js:95)
at showLights (script.js:83)
at script.js:88
I've looked around a lot for fixes to this error, and the majority of feedback is that it's related to the DOM and a wrapper will fix. I've found that a wrapper doesn't resolve. Similarly, I can't see that it's an issue with the CSS or HTML as the functions work ok until exit.
The looping functions are copied below:
// iterates through simon.array then allows button press
function showLights(x) {
if (x >= simon.array.length) {
clearTimeout(timer);
show(x);
allowPress();
} else {
show(x);
var timer = setTimeout(function(){
showLights(x+1);
},500);
}
}
// adds then removes flash class to light pads.
function show(x){
var display = document.getElementById("light" + simon.array[x]);
display.setAttribute("class", "flasher");
setTimeout(function(){
display.setAttribute("class", "game-box");
},500);
}
Apologies in advance for any errors or faux pas in posting this. I strongly suspect that I'll be kicking myself when this is fixed.
Kind Regards
Andy
The issue is related to you checking the length of an array, then trying to use an element of that array that does not exist. You are possibly also trying to set an attribute to an element that does not exist.
At a guess, this is the real cause of the issue:
if (x >= simon.array.length) {
clearTimeout(timer);
show(x);
allowPress();
Simply removing show(x) should help. The reason is you are checking for the length of simon.array, then later in function show(x) you make a request for simon.array[x], but that is not going to find anything, as x is greater than the length of that array.
The other possible issue is in the following chunk, but could be solved a number of ways. One way is to check x before passing. Another is making sure the element (display) is not null before setting the attribute.
// adds then removes flash class to light pads.
function show(x){
var display = document.getElementById("light" + simon.array[x]);
display.setAttribute("class", "flasher");
setTimeout(function(){
display.setAttribute("class", "game-box");
},500);
}
My suggestion would be as follows:
// adds then removes flash class to light pads.
function show(x){
var display = document.getElementById("light" + simon.array[x]);
if (display) {
display.setAttribute("class", "flasher");
setTimeout(function(){
display.setAttribute("class", "game-box");
},500);
}
}
You may want to check out classList as well as an alternative to setAttribute.
Something else to consider instead of using setTimeout would be to use a CSS animation.
I am writing a code in java script to display a countdown from 10 to 0. Loop is working for alert but when i use document.getElementById the loop doesn't work and it shows 0. Here's My Code
heading is the id of h1
function msg(z)
{
try
{
for(var i=0;i<=10;i++)
{
var seconds=z-i;
document.getElementById("heading").innerHTML="Select T
The Multiples of 2 in"+" "+seconds+" "+"seconds";
}
}
catch(e)
{
document.write(e);
}
Have you use debug tools to verify if the problem is in the loop? You are not waiting any second in each loop iteration, so youll see the end result as it will execute in much less than a second, so youll see 0 (the final iteration)
Take a look at this post Javascript Second Counter as is basically the same as you are trying to do.
Hope this helps
I Changed My function to this and it's working fine.
P.S:- I Have Not added any constraints yet!
function msg(){
function timer()
{
seconds -=1;
document.getElementById("heading").innerHTML="Select The Multiples of 2 in"+" "+seconds+" "+"seconds";
}
var cancel=setInterval(timer,1000);
setTimeout(function(){if(cout<10){alert("Time Over You Lose!");}else{alert("You Have Completed Level 1");}},10000);
}
This question already has an answer here:
CasperJS posting only the last item multiple times from my for-loop
(1 answer)
Closed 6 years ago.
Im using phantomjs and casperjs to test out my website.
In my JavaScript I have a for loop using var i, and another var rando inside the loop which increments.
I am calling
console.log(i);
console.log(rando);
for testing, but it does not print the correct value to the command line. However, I know that the variable is changing, as the code does as intended, for example the for loop is incrementing.
I tried using
console.log("%d", i);
but no luck.
My Code using a suggested solution still no luck:
for (i=0; i<100000; i++) { //// first loop
casper.wait(13000, function () {
casper.then(function () {
console.log(String.valueOf(i));
console.log(String.valueOf(rando));
casper.click(x(('/html/body/div[2]/div/div[2]/div/article/div[2]/section[2]/a/span')));
console.log(timeStamp());
});
});
casper.then(function () {
casper.click(x(('/html/body/div[2]/div/div[1]/div/div/a[2]')));
});
if (rando == 14) {
casper.then(function () {
casper.click(x(('/html/body/div[2]/div/div[2]/div/article/header/span/button')));
console.log(timeStamp());
});
rando = 0;
} else {
rando++;
}
}
The result is printing i as 100000 and rando as 10 every time, even when they are incremented.
Try to use
console.log(String.valueOf(i))
If didn't work please show your code
You are probably not handling the promises that the methods to get values from the DOM return.
"Crawling" frameworks massively use promises, to retrieve values from the DOM, because most of the times those values are changed dynamically and are not available as soon as the DOM is retrieved to the client.
more info about Promises here
This is an old gist i made using webdriverjs wich is similar to casper/phantom: link to gist. I specifically made this gist to pratice promise handling.
I have this code that is supposed to generate a counter for a slideshow and then change the picture and the corresponding number color in the counter. However, after the slideshow cycles through twice, the counter changes to display:none and then reappears and disappears every time the slideshow begins its cycle.
//icons for newsreel guide
for(i=0;i<document.getElementsByClassName("news").length;i++){
var count=i+1;
$('#counter').append('<span class="count">'+count+'</span>');
}
//newsreel script
$(".news").hide();
setTimeout (function() {
var wait = $(".news:last").index()*12000+12000;
function newsreel(){
var i=0;
(function showNews(elem){
if(i==document.getElementsByClassName("count").length){
i=0;
}
document.getElementsByClassName("count")[i].style.color="#000";
elem.fadeIn(2000,function(){
elem.delay(8000).fadeOut(2000,function(){
document.getElementsByClassName("count")[i].style.color="#3159a0";
i=i+1;
$(this).next().length && showNews($(this).next());
});
});
})
( $(".news:first"));
setTimeout (arguments.callee, wait);
}/*end newsreel()*/
newsreel();
}, 2000);
At first I thought it was using the deprecated arguments.callee but I changed that and it still happens on cue. Any ideas?
I checked your code, and the problem is in this line :
$(this).next().length && showNews($(this).next())
.next() is getting the next sibling. Your counter is a sibling of .news. To solve your problem, do this:
$(this).next().length && showNews($(this).next('.news'))
That will select the next sibling with the class news.
I suspect it's because your showNews function is never running. I think the JavaScript engine is evaluating
(function showNews(elem){
//...
})
and
( $(".news:first"));
as two different expressions, rather than passing $(".news:first") as a parameter to showNews as you intend. Since ; at the end of a line is optional in JS, the parser will insert one automatically if the result is valid JavaScript. In this case, it defines a function but never calls it, then builds a jQuery sequence but never uses it.
Try removing the carriage return between the two:
(function showNews(elem){
//...
})($(".news:first"));
I'd like to use the setInterval function in jQuery in order to create an alert with the content of one array every 4 seconds. However my alerts show all the values of my array within a short amount of time and it stops for 4 seconds after having displayed all the values.
$.each(['html5', 'EDM', 'Coca Cola', 'creativity'], function(id,value) {
setInterval(function(){
alert(value);
}, 4000);
});
In this case, I'd like to display something like : Alert('html5') - 4 seconds - Alert('EDM') - 4 seconds - Alert('Coca Cola') - 4 seconds - Alert('creativity') - 4 seconds - Alert('html5') - 4 seconds - Alert('EDM') - 4 seconds - ...
Move the setInterval from the loop.
var arr = ['html5', 'EDM', 'Coca Cola', 'creativity'];
var index = 0;
setInterval(function() {
console.log(arr[index++ % arr.length]);
}, 4000);
Live DEMO
No jQuery needed.
Use a recursive setTimeout
var arr = ['html5', 'EDM', 'Coca Cola', 'creativity'];
var alertLoop = function(i) {
if (arr[i]) {
alert(arr[i]);
setTimeout(function(){alertLoop(i+1);}, 4000);
}
}
alertLoop(0);
Demo: http://jsfiddle.net/B5tJw/
Use of setInterval is discouraged. For an explanation, read here: http://bonsaiden.github.com/JavaScript-Garden/#other.timeouts
To summarise the problem:
setInterval fires the event at a regular interval, regardless of what else is happening on the page.
However, Javascript is not multi-threaded: it can only run one code sequence at a time. If setInterval is triggered while another code sequence is being run, the new code sequence will be blocked until the previous one is finished, and will wait for it.
If this happens repeatedly, you can end up with a large number of events waiting to be run.
You're using alert() to display your messages. alert() causes the code execution sequence to pause until the user responds to the message, but keeps it locked, so that other events cannot run their code. This is a particular problem for setInterval, because it fires new events at the specified time, regardless of whether something else is blocking the script.
The solution is to use setTimeout instead of setInterval.
setTimeout is only triggered once, but it is easy to tell it to trigger itself again inside its own function, so you can get the same effect as setInterval, but with much more control. Your code can wait until after the alert() has been accepted by the user before triggering the next event, which means that you won't get the problem of cascading events that can happen with setInterval.
Hope that helps explain things. The link I mentioned at the beginning is also very helpful.