Multiple Timers in Quiz with jQuery - javascript

I'm on a quiz, where you can pick an answer out of four answer possibilities (like who wants to be a millionaire). I want to add a counter of 7secs per question to it, if the counter ends, a button to the next question should appear.
I already have my basic code with jQuiz, but my problem is now, that I use always the same counter instance. So the timer of the first question is fine, but if you answer the next question and have some time left of the first one, both counters are displayed at the same time. I think my problem will be solved when I have multiple timer instances, but I don't know how to do this.
Here my code. Sorry about the bad structure, I'm a jQuery newbie.
$('.btn, .nxt').click(function(){
$(this).addClass("checked");
next(this);
var el = $('#progress');
el.width(el.width() + 116 + 'px');
});
function next(elem){
$(elem).parents('.questionContainer').fadeOut(300, function(){
var interval = window.setInterval(function() {
var counter = 0;
clearInterval(interval);
});
var counter = 0;
timer();
$(elem).parents('.questionContainer').next().fadeIn(300);
$('.nxt').hide();
});
};
function timer(){
var counter = 7;
var interval = window.setInterval(function() {
counter--;
$(".counter").html(counter);
if (counter == 0) {
$(".counter").html('');
$('.nxt').show();
clearInterval(interval);
}
}, 1000);
};​

I'm new at Stackoverflow and it's too hard for me to edit code in this textarea... Added fixed JS to jsfiddle.
Try to add your HTML to the same fiddle and test JS, hope it would work.
There are some fixes about structure (caching selections mostly) and added array for timers (with comments) you were asking for.
It'll be easier to debug when you add HTML :)
var quizObj = {
quizTimers: [], //timers array
$counter: $(".counter"),
$buttons: $('.btn, .nxt'),
$progress: $('#progress'),
next: function(elem){
$(elem).parents('.questionContainer').fadeOut(300, function(){
//clears the FIRST timer id in the timers array and removes it from array
clearInterval(quizObj.quizTimers.shift());
quizObj.timer();
$(elem).parents('.questionContainer').next().fadeIn(300);
$('.nxt').hide();
});
},
timer: function() {
var counter = 7;
var interval = window.setInterval(function() {
counter--;
$(".counter").html(counter);
if (counter == 0) {
$(".counter").html('');
$('.nxt').show();
clearInterval(interval);
}
}, 1000);
quizObj.quizTimers.push(interval);
}
}
quizObj.$buttons.click(function(){
$(this).addClass("checked");
quizObj.next(this);
quizObj.$progress.width(quizObj.$progress.width() + 116 + 'px');
});

Related

build slider using jquery & javascript

I built slider using jquery but it is very stupid. You can see it:
http://jsfiddle.net/Bf2Mv/
i think the problem is here:
$(".img img").fadeOut().attr("src", images[count % images.length]).fadeIn();
$(".text").fadeOut().html(text[textcount % text.length]).fadeIn();
how to fix the effects?
thanks a lot!
You probably wanted something like this:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/Bf2Mv/7/
count = 0,
text = [
"first img desc",
"2nd img desc",
"3rd img desc"],
imageCount = images.length,
rand = 6000;
function slide() {
changeImage(1)
rand = 6000;
}
function changeImage(delta) {
count += delta;
if (count < 0) count = imageCount - 1;
count %= imageCount;
$(".img img").fadeOut(function () {
$(this).attr("src", images[count]).fadeIn()
});
$(".text").fadeOut(function () {
$(this).html(text[count]).fadeIn();
});
}
(function loop() {
setTimeout(function () {
slide();
loop();
}, rand);
}());
$("#next").click(function () {
changeImage(1);
});
$("#prev").click(function () {
changeImage(-1);
});
Notes:
You only need a single counter if the images and text arrays are the same length.
You did not need to have modulus operators everywhere if the indexes are managed correctly (between 0 and length-1)
You need to correctly wrap around from 0 to length-1 and back the other way.
You need to change the images after they fadeout (hence the new callbacks in fadeout)
I refactored the change code, so it just takes a direction delta value. That way the same code can be reused by the timer, the next and the prev options.
The problem was on how the fadein/fadeout was defined. You need to use the jQuery fadein/fadeout finished parameter function.
$(".img img").stop().fadeOut('fast', function() {
var that = $(this);
that.attr("src", images[count]).fadeIn('fast', function() {
if (!LOOP_INTERVAL) {
startLoop(); // Continue the loop.
}
});
});
There were also some other issues on the indexes. Here's the solution: http://jsfiddle.net/Bf2Mv/45/
I hope this is what you meant. If you have questions about the answer, feel free to ask!

Allowing for maximum number of opened accordion sections using jQuery

I've looked all over the internet and I can't seem to find a good way to do this.
I've got an accordion menu that I've built primarily using addClass/removeClass and css. It has special functionality, the accordion tabs open after a delay on mouseover and they open and close on click. I can currently open all of them at once, but I'd like to limit this to 2 or 3 with the earliest selected panel closing after I hit that limit. So I'd either need to make the classes numbered and switch them on every action, or perhaps apply a variable that keeps track of the order in which the panels were selected and switch them.
Below is the code I have so far. I've only been able to get as far as keeping count of how many tabs there currently are open. Does anyone have an idea as to what the best way to approach this is?
var timer;
var counter = 0;
$('li.has-dropdown').mouseenter(function() {
dd_item = $(this);
if(!$(this).hasClass('expand-tab')){
timer = setTimeout ( function () {
$(dd_item).addClass('expand-tab');
counter++;
}, 200);
};
}).mouseleave(function(){
clearTimeout(timer);
console.log(counter);
}).click(function() {
if ($(this).hasClass('expand-tab')){
$(this).removeClass('expand-tab');
counter--;
console.log(counter);
}else{
$(this).addClass('expand-tab');
console.log(counter);
}
});
Add a incrementting data-index to each opened tab.
count the tabs on the end of the hover effect, if they are to many, sort them by the index, and hide the lowest/oldest.
var timer;
var index = 1;
$('li.has-dropdown').mouseenter(function() {
dd_item = $(this);
if(!$(this).hasClass('expand-tab')){
timer = setTimeout ( function () {
$(dd_item).addClass('expand-tab');
$(dd_item).attr('data-index', index++);
counter++;
}, 200);
};
}).mouseleave(function(){
clearTimeout(timer);
console.log(counter);
}).click(function() {
$(this).taggleClass('expand-tab'); // see jQuery toggleClass();
$(this).attr('data-index', index++);//this will add index on closed tabs also.. but it does not matter at the end.
});
if($('.expand-tab').length> 3){
//custom inline sorting function.
var expanded_tabs = $('.expand-tab').sort(function (a, b) {
return (parseInt( $(a).attr('data-index')) < parseInt( $(b).attr('data-index')) ? -1 : 1 ;
});
//time out .. effect etc.
expanded_tabs[0].removeClass('expand-tab');
}
P.S I don't like havving Hover and Click in the same place ... try to separate the events and call a unified collapseIfToMany function in on each event
This is a corrected version. I decided to use a variable for the maximum panels opened, this way you don't have to dig if you decide you want to change it, or if you add more to the code.
var timer;
var index = 1;
var maxOpen = 2;
$('li.has-dropdown').mouseenter(function() {
dd_item = $(this);
if(!$(this).hasClass('expand-tab')){
timer = setTimeout ( function () {
$(dd_item).addClass('expand-tab');
$(dd_item).attr('data-index', index++);
collapseIfTooMany();
}, 200);
};
}).mouseleave(function(){
clearTimeout(timer);
}).click(function() {
$(this).toggleClass('expand-tab'); // see jQuery toggleClass();
$(this).attr('data-index', index++);//this will add index on closed tabs also.. but it does not matter at the end.
});
function collapseIfTooMany(){
if($('.expand-tab').length > maxOpen){
//custom inline sorting function.
var expanded_tabs = $('.expand-tab').sort(function (a, b) {
return (parseInt( $(a).attr('data-index')) < parseInt( $(b).attr('data-index'))) ? -1 : 1 ;
});
//time out .. effect etc.
$(expanded_tabs[0]).removeClass('expand-tab');
}
};

Count how many seconds did the user hover an element using jquery or javascript?

just need a little help here. My problem is, how can I count the seconds when i hover a specific element. Like for example when I hover a button, how can i count the seconds did i stayed in that button after I mouseout?
An alternate solution using setInterval. DEMO HERE
var counter = 0;
var myInterval =null;
$(document).ready(function(){
$("div").hover(function(e){
counter = 0;
myInterval = setInterval(function () {
++counter;
}, 1000);
},function(e){
clearInterval(myInterval);
alert(counter);
});
});
A simple example
var timer;
// Bind the mouseover and mouseleave events
$('button').on({
mouseover: function() {
// set the variable to the current time
timer = Date.now();
},
mouseleave: function() {
// get the difference
timer = Date.now() - timer;
console.log( parseFloat(timer/1000) + " seconds");
timer = null;
}
});
Check Fiddle
How about this quick plugin I just knocked out, which will work on multiple elements, and without using any global variables:
(function($) {
$.fn.hoverTimer = function() {
return this.on({
'mouseenter.timer': function(ev) {
$(this).data('enter', ev.timeStamp);
},
'mouseleave.timer': function(ev) {
var enter = $(this).data('enter');
if (enter) {
console.log(this, ev.timeStamp - enter);
}
}
});
};
})(jQuery);
Actually disabling the functionality is left as an exercise for the reader ;-)
Demo at http://jsfiddle.net/alnitak/r9XkX/
IMHO, anything using a timer for this is a poor implementation. It's perfectly trivial to record the time without needing to use an (inaccurate) timer event to "count" seconds. Heck, the event object even has the current time in it, as used above.
This is exam:
var begin = 0;
var end = 0;
$('#btn').hover(function () {
begin = new Date().getTime();
});
$('#btn').leave(function () {
end = new Date().getTime();
sec = (end - begin) / 1000;
alert(sec);
});
One way to go about it would be the event.timeStamp method :
var initial_hover, exit_hover;
$('#ele').hover(
function(event){
initial_hover = event.timeStamp
console.log(initial_hover);
},
function(event){
exit_hover = event.timeStamp
$(this).html(exit_hover - initial_hover);
console.log(exit_hover);
}
);
jsfiddle
You've tagged the question with JQuery, so here's a jQuery solution.
$(element).on('mouseover', function(e){
$(e.target).data('hover-start', new Date().getTime());
});
$(element).on('mouseout', function(e){
// count the difference
var difference = new Date().getTime() - $(e.target).data('hover-start');
// clean up the data
$(e.target).data('hover-start', undefined);
console.log('Mouse was over for', difference/1000, 'seconds');
});
use setInterval and store value in variable. call the function on mouserover.
function mouseover(){
var start = 0;
setInterval(function(){
start++;
var count = start;
}, 1000);
}

How to make this a slow jQuery counter

I am currently busy with making a new website.
I would like to make a counter on my website that shows visitors how many websites I made.
I am currently using Javascript and jQuery to do this. The only problem is that while using the for loop, the result shows very fast and I would like it to count up slowly. This is the code I have so far:
$(document).ready(function() {
var websites = 10;
for (var i=0;i<websites;i++)
{
$('.webcounter').html(i);
}
});
Any one has an idea to making the counter go slow?
You can try this:
var interval = window.setInterval(func, delay[, param1, param2, ...]);
This timer works in seconds, you can put the code to run after it's complete in the else section:
Javascript
function countdown(count){
$('.webcounter').html(count);
count -= 1;
if(count >= 0)
setTimeout("countdown("+count+")", 1000);
else
alert("Countdown Complete");
}
$(document).ready(function() {
countdown(10);
}
HTML
<div class="webcounter">Webcounter Holder</div>​
Demo
http://jsfiddle.net/silver89/SBXAQ/8/
Use setInterval:
EXAMPLE
HTML
​<div class="websites">0</div>​​​​​​​​​​​​​​​​​​​​​​​​​​​
JQUERY
$(document).ready(function() {
var websites = 10;
var counter = 1;
var id = setInterval(function(){
$('.websites').text(counter);
counter++;
if(counter > websites){ clearInterval(id);}
}, 500);
});​
Just a quick guess, but try something like this (i'm at work and cant test myself, heheh)
var websites = 10, tmrSiteCount;
function siteCount(i) {
if (i <= websites) {
$('.webcounter').html(i);
tmrSiteCount = setTimeout(function() { siteCount(i++); }, 1000);
}
else {
clearTimeout(tmrSiteCount);
};
}
$(document).ready(function() {
tmrSiteCount = setTimeout(function() { siteCount(1); });
})

Hide download link for 10 seconds? js

hey, how can I have my download link hidden, and make a count down type thing. Maybe have it count down from 10 and once it's done that have the download link appear, it would be best to do it in js right?
does anyone know how to do this? :D
Thanks
Complete example:
<span id="countdown"></span>
<a id="download_link" href="download.zip" style="display:none;">Download</a>
<noscript>JavaScript needs to be enabled in order to be able to download.</noscript>
<script type="application/javascript">
(function(){
var message = "%d seconds before download link appears";
// seconds before download link becomes visible
var count = 10;
var countdown_element = document.getElementById("countdown");
var download_link = document.getElementById("download_link");
var timer = setInterval(function(){
// if countdown equals 0, the next condition will evaluate to false and the else-construct will be executed
if (count) {
// display text
countdown_element.innerHTML = "You have to wait %d seconds.".replace("%d", count);
// decrease counter
count--;
} else {
// stop timer
clearInterval(timer);
// hide countdown
countdown_element.style.display = "none";
// show download link
download_link.style.display = "";
}
}, 1000);
})();
</script>
You can use setInterval for this. setInterval behaves like a timer, where you can run a certain function periodically. Something like this should do the work(untested):
$(".link").hide();
var iteration = 0;
var timer = setInterval(function() {
if(iteration++ >= 10) {
clearTimeout(timer);
$(".link").show();
$(".counter").hide();
}
$(".counter").text(10 - iteration);
}, 1000);
This will initially hide the download link and run a function every second which counts down from 10. When we reaced ten, we hide the counter and show the link. ClearTimeout is used so that we don't count after we reached ten. Easy as dell.
Edit: As mentioned in the comments, this function is using jQuery to find the elements.
Take a look at the setTimeout function. You can do something like:
function displayLink() {
document.getElementById('link_id').style.display = 'block';
}
setTimeout(displayLink, 10000);
var WAIT_FOR_SECONDS = 10;
var DOWNLOAD_BUTTON_ID = "btnDownload";
if (document.body.addEventListener) {
document.body.addEventListener("load", displayDownloadButton, false);
} else {
document.body.onload = displayDownloadButton;
}
function displayDownloadButton(event) {
setTimeout(function() {
_e(DOWNLOAD_BUTTON_ID).style.display = "";
}, WAIT_FOR_SECONDS*1000);
}
function _e(id) {
return document.getElementById(id);
}

Categories

Resources