Javascript - register how long user pressed a given button during whole visit - javascript

I'm programming an experiment in Qualtrics and I basically need to create, with Javascript, a variable that tells me how long (total) participants held down any button. Pressing a button will display text to the participants and releasing it will make the text disappear, so basically it tells me how much time they had to read the text. So let's say they press the button three times, first for 30 seconds, second for 10 seconds and third for 2 seconds, this code should store the value 42.
What I have so far is this:
addEventListener("keydown", function(event) {
if (event.keyCode == 86)
document.getElementById("text").innerHTML = "Text to show";
var d1 = new Date();
document.getElementById("div1").innerHTML = d1.getTime();
});
addEventListener("keyup", function(event) {
if (event.keyCode == 86)
document.getElementById("text").innerHTML = "";
var d2 = new Data();
var d1 = parseFloat(document.getElementById("div1"));
var diff = d2 - d1.getTime();
var old = parseFloat(document.getElementById("div2"));
var old = old + diff;
document.getElementById("div2").innerHTML = old;
Qualtrics.SurveyEngine.setEmbeddedData("readingtime", totalTime);
});
I store the values in divs because I can't seem to reuse values from one event listener to the other (this is probably because I don't know enough about javascript and scopes). Oh, and the last function is just a Qualtrics-specific function to store the value in the database. Anyway, I can't get it to work, when I check the variable in the database it is simply empty. Anyone can spot what I'm doing wrong?

I did a few changes to your code:
Added global variables
Added few missing brackets
Attached listeners to window
Removed multiple calls to DOM elements
Created a function for each event listener
Rounded the elapsed time to seconds
var d0;
var d1;
var subtotal = 0;
var total = 0;
var div1 = document.getElementById("div1");
var text = document.getElementById("text");
window.addEventListener("keydown", dealWithKeyDown, false);
window.addEventListener("keyup", dealWithKeyUp, false);
function dealWithKeyDown(event) {
if (event.keyCode == 86) {
if (typeof d0 === 'undefined') {
d0 = new Date();
}
d1 = new Date();
subtotal = Math.round((d1.getTime() - d0.getTime()) / 1000);
div1.innerHTML = subtotal;
text.innerHTML = "Text to show";
}
}
function dealWithKeyUp(event) {
if (event.keyCode == 86) {
total = total + subtotal;
text.innerHTML = "";
d0 = undefined;
Qualtrics.SurveyEngine.setEmbeddedData("readingtime", total);
}
}

Okey dokey, since none of the posted answers seem to have been accepted, I'm gonna post my own.
There's really not that much to say about this solution, it's as easy as it gets, nicely put into objects, so that we know what's going on, and I am even giving you a fiddle for it!
There's one problem I don't know if I solved or not, but sometimes the button will show that it has been pressed for millions of seconds, I think that's because Key is not being initialized properly, which is pretty weird, but it happens rarely enough for me to put the burden of fixing it on you.
The code is here:
https://jsfiddle.net/vo2n1jw1/
Pasted over:
var Key = function(code)
{
this.code = code;
};
Key.prototype.time = 0;
Key.prototype.pressedAt = 0;
Key.prototype.getTimeInSeconds = function()
{
return this.time / 1000;
};
var Keyboard = function()
{
this.keys = [];
};
Keyboard.prototype.addOrGetKey = function(code)
{
var key = this.getKey(code);
if(!key)
{
key = new Key(code);
this.addKey(key);
}
return key;
};
Keyboard.prototype.addKey = function(key)
{
this.getKeys()[key.code] = key;
};
Keyboard.prototype.getKey = function(code)
{
return this.getKeys()[code];
};
Keyboard.prototype.getKeys = function()
{
return this.keys;
};
Keyboard.prototype.printAllKeysIntoElement = function(element)
{
var keys = this.getKeys();
var length = keys.length;
element.innerHTML = "";
for(var i = 0; i < length; i++)
{
var key = keys[i];
if(!key)
{
continue;
}
var keyElement = document.createElement("div");
keyElement.innerHTML = "Button: " + key.code + " has been pressed for " + key.getTimeInSeconds() + " seconds";
element.appendChild(keyElement);
}
};
var KeyboardListener = function(keyboard, element)
{
this.keyboard = keyboard;
this.container = element;
this.onKeyDownThis = this.onKeyDown.bind(this);
document.addEventListener("keydown", this.onKeyDownThis, false);
document.addEventListener("keyup", this.onKeyUp.bind(this), false);
};
KeyboardListener.prototype.onKeyDown = function(event)
{
console.log("press");
var keyboard = this.getKeyboard();
var code = event.keyCode;
var key = keyboard.addOrGetKey(code);
key.pressedAt = Date.now();
document.removeEventListener("keydown", this.onKeyDownThis, false);
return false;
};
KeyboardListener.prototype.onKeyUp = function(event)
{
console.log("release");
var keyboard = this.getKeyboard();
var code = event.keyCode;
var key = keyboard.addOrGetKey(code);
if(key.pressedAt)
{
key.time += Date.now() - key.pressedAt;
keyboard.printAllKeysIntoElement(this.container);
}
document.addEventListener("keydown", this.onKeyDownThis, false);
return false;
};
KeyboardListener.prototype.getKeyboard = function()
{
return this.keyboard;
};
var resultsElement = document.getElementById("results");
var keyboard = new Keyboard();
var listener = new KeyboardListener(keyboard, resultsElement);
There's 3 objects:
Key
Keyboard
KeyboardListener
They really do what they sound like.
Tell me, if you want anything explained.
Oh, one thing, I know you're not supposed to use arrays like this, but I was lazy.

You can try to create a variable outside both listeners, and outside functions, so you can use it anywhere.
And I think you are doing well by getting the times of Dates.
var firstTime = new Date();
var totalTime = 0;
addEventListener("keydown", function(event) {
if (event.keyCode == 86) {
document.getElementById("text").innerHTML = "Text to show";
firstTime = new Date();
}
});
addEventListener("keyup", function(event) {
if (event.keyCode == 86) {
document.getElementById("text").innerHTML = "";
var d2 = new Date();
var diff = d2.getTime() - firstTime.getTime();
totalTime += diff;
Qualtrics.SurveyEngine.setEmbeddedData("readingtime", totalTime);
}
});

It's better to declare d1 & d2 variables global instead of using html elements as storage.
var d1, d2;
var total_time = 0;
var key_pressed = false;
addEventListener("keydown", function(event) {
if (event.keyCode == 86) {
if (!key_pressed)
d1 = new Date();
key_pressed = true;
}
});
addEventListener("keyup", function(event) {
if (event.keyCode == 86) {
key_pressed = false;
d2 = new Date();
total_time += d2.getTime() - d1.getTime();
Qualtrics.SurveyEngine.setEmbeddedData("readingtime", total_time);
}
});
When the 'v' key is pressed and hold, keydown listener is called repeatedly. That's why there is boolean variable i.e. "key_pressed" to detect hold key first time.

Where does the "totalTime" get assigned?
Is your totalTime has any value?
Did you try to debug the javascript using the browser console?
If you don't want to store data to divs, u can store it within global vars.
var times = {
start: 0,
total: 0
}
addEventListener("keydown", function(event) {
if (event.keyCode == 86) {
// i think your hole code should be executed only on releasing this one button
document.getElementById("text").innerHTML = "Text to show";
times.start = new Date();
}
});
addEventListener("keyup", function(event) {
if (event.keyCode == 86) {
// i think your hole code should be executed only on releasing this one button
document.getElementById("text").innerHTML = "";
var diff = new Date().getTime() - times.start.getTime();
times.total = times.total + diff;
Qualtrics.SurveyEngine.setEmbeddedData("readingtime", times.total);
}
});
So you can use the var times outside of the event listener function to declare it global.
I noticed that you used the if ().. without { and }, so only the next line is affected, im dont shure if you want that.

Related

One time initialization for JavaScript variable

I am developing a JavaScript for a webpage. This script has to create a popup, when the user is idle for a certain time. When the popup shows up, the user can choose to either close the popup or to minimize it.
In case of closing the popup, further opened pages within the website shall not open the popup anymore. In case of minimizing, it should not do either. Nonetheless when the user has a certain idle time on any page the first time, it shall appear.
It works in so far, that the pop up is created and also the closing of the pop works (and that it does not open anymore). But it does not work a refresh of the page anymore. So the storing does not work. And I know it is, because of my variables and a refresh also restarts the script again, so the initialization of the variables does rewrite the session value.
So basically my question is: How do it do the 1st time initialization of the variables, which than are furtherly used after a refresh?
My code is the following:
var isClosed = new Boolean(false);
var isShrinked = new Boolean(false);
var test = "Tesst";
sessionStorage.setItem("session", isClosed=false);
function close_popup() {
$('#' + 'box').fadeOut('slow');
sessionStorage.setItem("session", isClosed=true);
}
(function idelor(){
document.onclick = document.onmousemove = document.onkeypress = function() {
idleCounter = 0;
};
window.setInterval(function() {
if (sessionStorage.getItem("session").toString() == "false") {
if (isShrinked == false) {
if (++idleCounter >= IDLE_TIMEOUT) {
var scriptCode = document.createElement('p');
scriptCode.id = 'Sentotal';
document.getElementsByTagName('body')[0]
.appendChild(scriptCode);
document.getElementById("Sentotal").innerHTML = boxTotal;
}
}
}
}, interval);}());
You can use cookie for this matter.
//A simple function to get the value stored in cookie;
var getCookie = name =>
document.cookie.split(';')
.map(token => token.trim('').split('='))
.reduce((prev, curr) =>
(prev[curr[0]] = curr[1]) && prev, {})[name],
myPopup = () => {
if (!getCookie('noPopUp')) {
console.log('your popup logic');
document.cookie = 'noPopUp=true'
}
},
reset = () => {
document.cookie = 'noPopUp=true; expires=' + new Date();
};
reset(); //Remove this and myPopUp will do nothing until you restart your browser.
myPopUp();
myPopUp();
Cookie resets (by default) when browser closes.
I used Hin Fan Chan's suggestion of using cookies, and have the following, stable working solution coded:
Just two variables now as constant names for the Cookies:
var CLOSE_CONSTANT = "CloseCookie";
var MINIMIZE_CONSTANT = "MinimizeCookie";
Simple functions for creating and getting the cookies. Note, that "error" in getCookie(...) is very important for the initialization of the script!:
function setCookie(name, state) {
var cname = name;
var value = state;
document.cookie = cname + "=" + value;
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "error";
}
I also build a cookieChecker(...) function, which automatically fills error-Cookies (those, who are not existing atmo) with "false":
function cookieChecker(name) {
switch (getCookie(name)) {
case "error":
setCookie(name, "false");
break;
default:
break;
}
}
Now the final function, which is the only function being opened by the HTML. cookieChecker(...) is used twice: For the minimization and the closing of the popup. These two functions simply set the state of a cookie to true (and fading the box out):
(function idelor() {
var minutes = false;
var interval = minutes ? 60000 : 1000;
var IDLE_TIMEOUT = 5;
var idleCounter = 0;
document.onclick = document.onmousemove = document.onkeypress = function() {
idleCounter = 0;
};
cookieChecker(MINIMIZE_CONSTANT);
cookieChecker(CLOSE_CONSTANT);
window
.setInterval(
function() {
switch (getCookie(CLOSE_CONSTANT) + " "
+ getCookie(MINIMIZE_CONSTANT)) {
case "false false":
if (++idleCounter >= IDLE_TIMEOUT) {
var scriptCode = document.createElement('p');
scriptCode.id = 'Sentotal';
document.getElementsByTagName('body')[0]
.appendChild(scriptCode);
document.getElementById("Sentotal").innerHTML = BOXTOTAL;
}
default: break;
}
}, interval);
}())

Force Meteor To Refresh / Re-render Templates?

*For reference I'm using iron router.
Instead of a sign in page I have this global sign in form embedded in an nav (aka on every page).
Right now I'm doing a really hacky refresh to reload the page once a user logs in.
I would like to just reload to the template aka not refresh the whole page.
Basically just want the templates rendered function to rerun on login.
Here's my current login code:
'submit #login': function(event, template){
event.preventDefault();
var handle = template.find('#usernameLogin').value;
var secretKey = template.find('#passwordLogin').value;
Meteor.loginWithPassword(handle, secretKey, function(err){
if (err) {
alert(err);
}else{
$('#close').click();
/* replace this with reactive ajax or whatever when you can! */
Meteor._reload.reload();
}
});
},
My render function which I think may be the real issue now:
Template.tournament.rendered = function () {
thisCampaign = this.data;
var self = this;
if (this.data.tournament.live) {
/* if theres a registered user */
if (Meteor.userId()) {
/* Select a winner box */
var participants = $('.participant-id');
var currentParticipant;
var nextRound;
var thisMatch;
var nextMatch;
var bracket;
participants.map(function(index, value){
if ($(value).text() === Meteor.userId()) {
if ($(value).parent().find('.participant-status').text() === 'undetermined') {
nextRound = $(value).parent().find('.participant-round').text();
thisMatch = $(value).parent().find('.participant-match').text();
bracket = $(value).parent().parent().parent().find('.participant');
};
};
});
nextRound = parseInt(nextRound) + 1;
nextMatch = Math.round(parseInt(thisMatch)/2) - 1;
if (parseInt(thisMatch) % 2 != 0) {
currentParticipant = 0;
}else{
currentParticipant = 1;
}
var winnerOptions = '';
var winnerBox = $('<div class="select-winner">');
if (bracket) {
bracket.map(function(index, value) {
winnerOptions += '<span class="winner-option"> '+$(value).find('.participant-title').text()+' <div class="winner-info"> '+$(value).find('a').html()+' </div> </span>'
});
winnerBox.append(winnerOptions);
$($($('.round'+nextRound).find('li')[nextMatch]).find('.participant')[currentParticipant]).removeClass('loser').addClass('undetermined');
$($($('.round'+nextRound).find('li')[nextMatch]).find('.participant')[currentParticipant]).find('a').addClass('tooltip').html(winnerBox);
};
}else{
}
}else{
/* Tournament Start Time */
var tournamentStartTime = function(){
var d = new Date();
var n = d.getTime();
var currentTime = TimeSync.serverTime(n);
var startTime = self.data.card.startTime;
var difference = startTime - currentTime;
var hoursDifference = Math.floor(difference/1000/60/60);
difference -= hoursDifference*1000*60*60
var minutesDifference = Math.floor(difference/1000/60);
difference -= minutesDifference*1000*60
var secondsDifference = Math.floor(difference/1000);
/* if ends (make tournament live server side?) */
if (hoursDifference < 0 || minutesDifference < 0 || secondsDifference < 0) {
Meteor.clearInterval(tStartTime);
Session.set("tournamentStartTime", false);
}else{
if (hoursDifference < 10) {hoursDifference = "0"+hoursDifference;}
if (minutesDifference < 10) {minutesDifference = "0"+minutesDifference;}
if (secondsDifference < 10) {secondsDifference = "0"+secondsDifference;}
var formattedTime = hoursDifference + ':' + minutesDifference + ':' + secondsDifference;
Session.set("tournamentStartTime", formattedTime);
}
};
Session.set("tournamentStartTime", '00:00:00');
tournamentStartTime();
var tStartTime = Meteor.setInterval(tournamentStartTime, 1000);
/* Allow new user sign up */
var alreadySignedUp = false;
var usersSignedUp = $('.participant-id')
usersSignedUp.map(function (index, user) {
if ($(user).text().trim() === Meteor.userId()) {
alreadySignedUp = true;
}
});
if (this.data.card.host != Meteor.user().username && !(alreadySignedUp)) {
var openSlots = [];
var allSlots = $('.participant');
allSlots.map(function (index, participant) {
if ($(participant).find('.participant-title').text().trim() === '' && !($(participant).hasClass('loser'))) {
openSlots.push(participant);
}
});
openSlots.map(function (openSlot, index) {
$(openSlot).removeClass('winner').addClass('undetermined');
});
}
/* if theres a registered user */
if (Meteor.userId()) {
}else{
}
}
};
From what i can see there, your rendered function would not work as you expect as the template may render while the loggingIn state is still occuring...
My suggestion would be to use something along the lines of {{#if currentUser}} page here{{/if}} and then put the code you are trying to run in the rendered in a helper inside that currentUser block that way it would only display and be called if there is a logged in user, otherwise it would not show up and you would not need to re-render the page to perform any of that.
Basically once the user has logged in, any helper (other than rendered) that has the Meteor.userId() or Meteor.user() functions being called would re-run automatically, otherwise you could perform login actions inside a Tracker.autorun function if they are global to your app per client.

Javascript error: object is not a function in a video poker script

So I have been writing a script to play a video (or really text-based) poker game as an exercise in learning Javascript. I have everything working to play through an instance of the game once, but on trying to run it a second time, it develops an error: "Uncaught TypeError: object is not a function"
This error comes up when trying to create a new hand.
Here is the relevant code, I left a few functions out that don't seem to be causing any issues:
//object constructor for card
function card(suite, faceValue) {
this.suite = suite,
this.faceValue = faceValue
}
//object constructor for hand
function hand(cards, handName, score, docHandName) {
this.cards = cards,
this.handName = handName,
this.score = score,
this.docHandName = docHandName
}
var deck = new Array;
var buildDeck = function() {
for (var i = 0; i <= 52; i++) {
if (i < 13) {
deck[i] = new card("Spades", i + 2);
}
else if (i < 26) {
deck[i] = new card("Clubs", i - 11);
}
else if (i < 39) {
deck[i] = new card("Hearts", i - 24);
}
else if (i < 52) {
deck[i] = new card("Diamonds", i - 37);
}
}
}
//pulls a card from location in deck specified by randomSpot()
var pullCard = function(spot) {
var newCard = deck[spot];
deck.splice(spot, 1);
return newCard;
}
//takes away a card each time
//passes into pullCard(spot) as spot
var pullCount = 0;
var randomSpot = function() {
var x = Math.floor(Math.random() * (52 - pullCount));
pullCount++;
return x;
}
var dealFiveCards = function() {
var card1 = pullCard(randomSpot());
var card2 = pullCard(randomSpot());
var card3 = pullCard(randomSpot());
var card4 = pullCard(randomSpot());
var card5 = pullCard(randomSpot());
var fiveCards = [card1, card2, card3, card4, card5];
return fiveCards;
}
function createNewHand() {
newHand = new hand();
newHand.cards = dealFiveCards();
return newHand;
}
var playOneGame = function() {
buildDeck();
hand = createNewHand();
hand.cards.sort(compare);
assignHandScore();
wager = prompt("How much do you bet?");
printHandValue();
dealAgain();
hand.cards.sort(compare);
assignHandScore();
payout = pays(wager);
printHandValue();
printPayout();
}
playAgain = "Y";
while (playAgain === "Y") {
playOneGame();
playAgain = prompt("Would you like to play again? Y/N").toUpperCase();
}
So the error occurs when trying to run the playOneGame() function a second time. The first time runs fine and a hand is created. The second time when it gets to hand = createNewHand(); it gives the object is not a function error.
To be clear, I have the hand created as an object, which contains properties cards, handName, score, docHandName where cards is an array of card objects, themselves containing properties of suite, faceValue.
The error gives the line newHand = new hand(); in function createNewHand() as the reference line.
Help?
The second line of playOneGame is overriding your global hand function with an instance of hand. So when createNewHand runs again hand it is no longer the same thing.
You should probably rename the function hand to Hand.

Cookie Code not removing opened element of cookie

var openClose = $('.openClose');
openClose.on('click', function() {
var cook = ReadCookie('slideHide'),
miniParent = $(this).parent().parent().parent().children('.main-content'),
miniDisp = miniParent.css('display');
if (miniDisp ==="block") {
KillCookie('slideHide');
$(this).parent().parent().parent().children('.main-content').slideUp();
var slide = cook + "," + "#"+$(this)
.parent()
.parent()
.parent()
.parent().attr("id") +
" #"+$(this).parent()
.parent().parent().attr("id");
SetCookie('slideHide', slide, 100);
}
else
{
$(this).parent().parent().parent().children('.main-content').slideDown();
var newCookie=[];
var a= $('.module').children('.main-content').filter(":hidden");
for(var i=0;i<a.length;i++){
var d = $(a[i++]);
var c = "#"+d.parent('.module').attr('id');
}
newCookie= c;
console.log(newCookie);
KillCookie('slideHide');
SetCookie('slideHide',d, 100);
}
});
These are my cookie functions:
function SetCookie(cookieName,cookieValue,nDays) {
var today = new Date();
var expire = new Date();
if (nDays==null || nDays==0) nDays=1;
expire.setTime(today.getTime() + 3600000*24*nDays);
document.cookie = cookieName+"="+escape(cookieValue)
+ ";expires="+expire.toGMTString(),';path = /';
}
function KillCookie(cookieName) {
SetCookie(cookieName,"", - 1);
}
function ReadCookie(cookieName) {
var theCookie=""+document.cookie;
var ind=theCookie.indexOf(cookieName+"=");
if (ind==-1 || cookieName=="") return "";
var ind1=theCookie.indexOf(";",ind);
if (ind1==-1) ind1=theCookie.length;
return unescape(theCookie.substring(ind+cookieName.length+1,ind1));
}
Setting the cookie to make it slideUp and stay hidden works, but when I try to open it, it slidesDown, then I refresh the page it doesn't stay open like it should.
To sort of get the picture - http://jsfiddle.net/zRT9u/
If you need to know more please ask me I am willing to provide more!
I edited the javascript it almost works but I am not getting all the objects that I need
NEW EDIT- Tried the $.map() function but when I open one, and refresh all of them are now open?
else {
$(this).parent().parent().parent().children('.main-content').slideDown();
KillCookie('slideHide');
var newCookie=[];
var a= $('.module').children('.main-content').filter(":hidden");
var c = $.map(a,function(n,i){
return $(n).parent().attr('id');
});
newCookie= c;
SetCookie('slideHide',newCookie, 100);
}
Fixed it by using $.map and .join()
var openClose = $('.openClose');
openClose.on('click', function() {
var cook = ReadCookie('slideHide'),
miniParent = $(this).parent().parent().parent().children('.main-content'),
miniDisp = miniParent.css('display');
if (miniDisp ==="block") {
KillCookie('slideHide');
$(this).parent().parent().parent().children('.main-content').slideUp();
var slide = cook+","+ "#"+$(this).parent().parent().parent().attr("id");
SetCookie('slideHide', slide, 100);
} else {
$(this).parent().parent().parent().children('.main-content').slideDown();
KillCookie('slideHide');
var newCookie=[],
a= $('.module').children('.main-content').filter(":hidden"),
c = $.map(a,function(n,i){
return "#"+$(n).parent().attr('id');
});
newCookie= c.join(',');
SetCookie('slideHide',newCookie, 100);
}
});
By creating a "global" array and then using the $.map function as well as adding "#"+ to the map function I was able to get the actual ID names. Then I set newCookie to c.join(',') and everything works perfectly after that!

Something horribly wrong with my js code, anyone can help me debug?

I'm trying to write this tool, to animate a game map from a range of dates. The flow is like this:
1st: choose game world
2nd: set map display parameters (date range, map type and animation speed)
3rd: the js code grab png file according to the dates and display them one by one according to the animation speed
The problem I'm having is this:
if you just click on one world, and click animate, everything is fine, the animation displays correctly. Then if you choose another world (without refreshing the page), the animation either flickers or somehow displaying image from other worlds. and I can't figure out what's causing this (I'm totally n00b at js)
$(function(){
$("#image_area").hide();
$("#tw_image").hide();
$('#W40').click(function(){
$("#tw_image").hide();
show_image_area('40');
});
$('#W42').click(function(){
$("#tw_image").hide();
show_image_area('42');
});
$('#W56').click(function(){
$("#tw_image").hide();
show_image_area('56');
});
});
function show_image_area(world){
$("#tw_image").hide();
if(world == "40" || world == "42" || world == "56"){
$("#map_notice").remove();
$("#image_area").prepend('<div id="map_notice">Map for W'+world+' available from <span id="date_highlight">April 7th 2011</span>, all previous dates invalid and will not have map available</div>');
}
$("#date_from").datepicker({ showAnim: 'blind' });
$("#date_to").datepicker({ showAnim: 'blind' });
$('#image_area').show();
$("#animate").click(function(){
$("#tw_image").hide();
var date_from = $("#date_from").val();
var date_to = $("#date_to").val();
if(!(date_from && date_to)){
alert("From and To dates required.")
return false;
}
var map_type = $("#map_type").val();
var speed = $("#speed").val();
var days = daydiff(parseDate(date_from), parseDate(date_to));
var date_one = new Date(Date.parse(date_from));
var b = date_one.toISOString().split("T")[0].split("-");
var c = get_map_type(map_type) + b[0] + b[1] + b[2];
var width = get_map_type_width(map_type);
var img_load = "" + world + "/" + c + ".png";
$('#image_area').load(img_load, function(){
$("#tw_image").attr("width", width);
$("#tw_image").attr("src", img_load);
$("#tw_image").show();
$("#debug").html("world = "+world);
});
var i = 0;
var interval = setInterval(
function(){
date_one.setDate(date_one.getDate() + 1);
b = date_one.toISOString().split("T")[0].split("-");
c = get_map_type(map_type) + b[0] + b[1] + b[2];
var src_one = "" + world + "/"+c+".png";
var img = new Image();
img.src = src_one;
img.onload = function(){
$("#tw_image").attr("src", img.src);
$("#debug").html("world = "+world);
}
i++;
if(i >= days) clearInterval(interval);
},speed);
});
}
function get_map_type(map_type){
if(map_type == "topk"){
return "topktribes";
}
if(map_type == "toptribe"){
return "toptribes";
}
if(map_type == "topnoble"){
return "topnoblers";
}
}
function get_map_type_width(map_type){
if(map_type == "topk"){
return 1000;
}
if(map_type == "toptribe"){
return 1300;
}
if(map_type == "topnoble"){
return 1300;
}
}
function parseDate(str) {
var mdy = str.split('/');
return new Date(mdy[2], mdy[0]-1, mdy[1]);
}
function daydiff(first, second) {
return (second-first)/(1000*60*60*24)
}
Ok I think I have a solution here although its not what I thought it was going to be. Basically every time you are calling image_area_world you are creating a new click handler on the animate button. Due to the way JavaScript scope works the World variable is kept the same for that click handler at the point of creation.
Anyway to solve this problem what you can try is this just before you define your click handler.
$("#animate").unbind("click");
$("#animate").click(function () { *code* }
A couple of tools to help you out.
Visual Event
Firebug
Also a bit explaining how JavaScript Scope and Closures work

Categories