我有这个倒计时
我想在onload中进行以下工作,但我显然有关闭的问题
for (var o in myDates) {
var myDate = myDates[o];
var iid = o;
funcs[o] = function() {
var dateFuture = new Date();
dateFuture.setSeconds(dateFuture.getSeconds()+myDate.durationInSecs);
GetCount(dateFuture,iid);
}
myDates[iid].tId = setTimeout("funcs['"+iid+"']()",myDates[o].delay*1000);
}
以下代码有效。 但它有一个隐式eval和2个全局变量,我想像上面的非工作代码一样循环
<html>
<head>
<script type="text/javascript">
var myDates = {
d0: {
durationInSecs: 5,
delay:0,
repeat:false,
duringMessage : " until something happens",
endMessage : " something happened",
repeatMessage : ""
},
d1: {
durationInSecs: 10,
delay:3,
repeat:true,
duringMessage : " until something else happens",
endMessage : " something else happened",
repeatMessage : "This will repeat in 3"
}
}
var funcs = {};
window.onload=function(){
// the below could be done in a loop, if I was better in closures
setTimeout(function() {
funcs["d0"] = function() {
var myDate = myDates["d0"];
var dateFuture0 = new Date();
dateFuture0.setSeconds(dateFuture0.getSeconds()+myDate.durationInSecs);
GetCount(dateFuture0,"d0");
}
funcs["d0"]();
},myDates["d0"].delay*1000);
// ---------------
setTimeout(function() {
funcs["d1"] = function() {
var myDate = myDates["d1"];
var dateFuture1 = new Date();
dateFuture1.setSeconds(dateFuture1.getSeconds()+myDate.durationInSecs);
GetCount(dateFuture1,"d1");
}
funcs["d1"]();
},myDates["d1"].delay*1000);
};
//######################################################################################
// Author: ricocheting.com
// Version: v2.0
// Date: 2011-03-31
// Description: displays the amount of time until the "dateFuture" entered below.
// NOTE: the month entered must be one less than current month. ie; 0=January, 11=December
// NOTE: the hour is in 24 hour format. 0=12am, 15=3pm etc
// format: dateFuture1 = new Date(year,month-1,day,hour,min,sec)
// example: dateFuture1 = new Date(2003,03,26,14,15,00) = April 26, 2003 - 2:15:00 pm
// TESTING: comment out the line below to print out the "dateFuture" for testing purposes
//document.write(dateFuture +"<br />");
//###################################
//nothing beyond this point
function GetCount(ddate,iid){
dateNow = new Date(); //grab current date
amount = ddate.getTime() - dateNow.getTime(); //calc milliseconds between dates
delete dateNow; // is this safe in IE?
var myDate = myDates[iid];
// if time is already past
if(amount < 0){
document.getElementById(iid).innerHTML=myDate.endMessage;
if (myDate.repeat) {
setTimeout(funcs[iid],myDate.delay*1000);
document.getElementById(iid).innerHTML=myDate.repeatMessage;
}
}
// else date is still good
else{
secs=0;out="";
amount = Math.floor(amount/1000);//kill the "milliseconds" so just secs
secs=Math.floor(amount);//seconds
out += secs +" "+((secs==1)?"sec":"secs")+", ";
out = out.substr(0,out.length-2);
document.getElementById(iid).innerHTML=out + myDate.duringMessage;
document.title=iid;
setTimeout(function(){GetCount(ddate,iid)}, 1000);
}
}
</script>
</head>
<body>
<div>
<span id="d0" style="background-color:red">!!</span>
<span style="float:right¨;background-color:green" id="d1">??</span>
</div>
</body>
答案 0 :(得分:1)
你陷入了在循环中声明闭包的陷阱。内部函数关闭了变量 myDate和而不是的值。这是特别意外的,因为变量应该具有块范围而不是多次迭代(不是Javascript中的情况 - 一切都是函数范围)。
你可以通过一个闭包制造者功能来解决这个问题。这样,您可以创建一个新的变量实例,以便随意关闭。
<强> WRONG 强>
var i;
for(i=0; i<xs.length; i++){
something = function(){
f(i);
};
}
//all closures share the i variable and will have it
//be i=xs.length in the end. We don't want that.
确定强>
function make_handler(i){
return function(){
f(i);
};
//each call gets its own copy of i
}
var i;
for(i=0; i<xs.length; i++){
something = make_handler(i);
}
或封闭制造商内联
var i;
for(i=0; i<xs.length; i++){
something = (function(i){
return function(){
f(i);
};
}(i));
}