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 speedThe 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_开发者_JAVA百科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
精彩评论