创建新对象后,如何防止旧对象丢失?
How do I prevent loss of older objects, after I create a new one?
我会尽可能简单地解释一下。
我正在尝试制作一个计时器应用程序来练习。用户应该能够添加一个新的对象,它将是一个计时器 + stop/start 个按钮。
此时,它正在处理一个对象,但是当我创建另一个对象时,旧对象停止工作(我相信它失去了指向它的指针,或类似的东西),而新对象开始工作。
别担心,关于按钮功能,这并不重要,我只想了解如何在创建新对象后保存对象。
这是 JS:
var startTime = 0;
var itemNum = 0;
var obName;
var arrayForTimers = [];
function timerObject(obName) {
this.nameField = "start";
this.classField = "timer";
this.block = " ";
this.obName = obName;
this.startButton = " ";
this.stopButton = " ";
this.placeholder = document.getElementsByClassName("timer-placeholder")[0];
this.addBlock = function () {
this.block = document.createElement("DIV");
this.block.className = this.classField;
this.block.className += " " + this.obName;
this.placeholder.appendChild(this.block);
}
this.renderTime = function () {
this.startTime = startTime;
this.endTime = new Date();
// time difference in ms
this.timeDiff = this.endTime - this.startTime;
// strip the miliseconds
this.timeDiff /= 1000;
// get seconds
this.seconds = Math.round(this.timeDiff % 60);
// remove seconds from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get minutes
this.minutes = Math.round(this.timeDiff % 60);
// remove minutes from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get hours
this.hours = Math.round(this.timeDiff % 24);
this.block.innerHTML = this.hours + " h " + this.minutes + " min " + this.seconds + " sec";
// window.setInterval('this.obName.renderTime()',1000);// Uncomment if you want to test your PCs limit
}
this.renderButtons = function () {
var timePassed;
//this.parentTimer = document.getElementsByClassName("timer "+this.obName)[0];
this.startButton = document.createElement("INPUT");
this.startButton.setAttribute("type", "button");
this.startButton.setAttribute("value", "start");
this.startButton.className = "start " + this.obName;
this.stopButton = document.createElement("INPUT");
this.stopButton.setAttribute("type", "button");
this.stopButton.setAttribute("value", "stop");
this.stopButton.className = "stop " + this.obName;
this.placeholder.insertBefore(this.startButton, this.block);
this.placeholder.insertBefore(this.stopButton, this.block);
this.startButton.addEventListener("click", function () {
//if (this.hours === 0 && this.minutes === 0 && this.seconds === 0){
this.startTime = new Date();
// }
tm = window.setInterval('obName.renderTime()', 1000);
})
this.stopButton.addEventListener("click", function () {
window.clearInterval(tm);
//timePassed = this.endTime - this.startTime;
//endTime = new Date();
// timePassed = endTime - startTime;
})
//give listener to clear and start interval
}
};
function createNewTimer() {
obName = document.getElementById("ObName").value;
if (obName !== "") {
obName = new timerObject(obName);
obName.addBlock();
obName.renderButtons();
startTime = new Date();
obName.renderTime();
//arrayForTimers.push(obName);
//window.setInterval('obName.renderTime()',1000);
} else {
document.getElementById("ObName").value = "Fill me";
}
};
这里有一个JsFiddlehttp://jsfiddle.net/3qxoea52/4/
P.S。对不起我的语法,不是我的母语。
谢谢。
问题就在这里
tm = window.setInterval('obName.renderTime()', 1000);
这意味着当您单击任何启动按钮时,它将始终启动当前与 obName 关联的对象。
此外,您只有一个全局变量 tm
来存储计时器,所以当您这样做时
window.clearInterval(tm);
正在清除上次设置的定时器。
而且您还有一个全局 startTime
,这会导致所有计时器在您创建新计时器时重置。
另一个问题是当你停止每个定时器时,你没有任何东西来存储时间,所以如果你停止然后重新启动它,它不会在同一点继续。
您可以通过以下方式解决这些问题:
- 使用
self = this
创建对象的稳定引用
- 使用
function.bind
确保事件处理程序将绑定到正确的计时器对象
- 添加一个属性
this.startDiff
以便在您停止然后重新启动时钟时保存时间
- 使
tm
成为 TimerObject
中的局部变量
- 在对象内而不是在对象外设置
this.startTime
。
-- 如以下代码所示 (jsfiddle)
function TimerObject(obName) {
var self = this,
tm;
this.startTime = new Date();
this.startDiff = 0;
this.nameField = "start";
this.classField = "timer";
this.block = " ";
this.obName = obName;
this.startButton = " ";
this.stopButton = " ";
this.placeholder = document.getElementsByClassName("timer-placeholder")[0];
this.addBlock = function () {
this.block = document.createElement("DIV");
this.block.className = this.classField;
this.block.className += " " + this.obName;
this.placeholder.appendChild(this.block);
};
this.renderTime = function () {
var timeDiff = new Date() - this.startTime + this.startDiff;
this.timeDiff = timeDiff;
timeDiff /= 1000;
// get seconds
this.seconds = Math.round(timeDiff % 60);
// remove seconds from the date
timeDiff = Math.floor(timeDiff / 60);
// get minutes
this.minutes = Math.round(timeDiff % 60);
// remove minutes from the date
timeDiff = Math.floor(timeDiff / 60);
// get hours
this.hours = Math.round(timeDiff % 24);
this.block.innerHTML = this.hours + " h " + this.minutes + " min " + this.seconds + " sec";
// window.setInterval('this.obName.renderTime()',1000);// Uncomment if you want to test your PCs limit
};
this.renderButtons = function () {
var timePassed;
//this.parentTimer = document.getElementsByClassName("timer "+this.obName)[0];
this.startButton = document.createElement("INPUT");
this.startButton.setAttribute("type", "button");
this.startButton.setAttribute("value", "start");
this.startButton.className = "start " + this.obName;
this.stopButton = document.createElement("INPUT");
this.stopButton.setAttribute("type", "button");
this.stopButton.setAttribute("value", "stop");
this.stopButton.className = "stop " + this.obName;
this.placeholder.insertBefore(this.startButton, this.block);
this.placeholder.insertBefore(this.stopButton, this.block);
this.startButton.addEventListener("click", function () {
//if (this.hours === 0 && this.minutes === 0 && this.seconds === 0){
self.startTime = new Date();
// }
tm = window.setInterval(self.renderTime.bind(self), 1000);
});
this.stopButton.addEventListener("click", function () {
window.clearInterval(tm);
self.startDiff = self.timeDiff;
console.log(':', self, self.startDiff);
//timePassed = this.endTime - this.startTime;
//endTime = new Date();
// timePassed = endTime - startTime;
});
//give listener to clear and start interval
};
}
function createNewTimer() {
obName = document.getElementById("ObName").value;
if (obName !== "") {
obName = new TimerObject(obName);
obName.addBlock();
obName.renderButtons();
obName.renderTime();
//window.setInterval('obName.renderTime()',1000);
} else {
document.getElementById("ObName").value = "Fill me";
}
}
代码存在几个问题:
1. 一些函数没有绑定到正确的上下文 (this)。
2. 设置为 "obName" 的引用是全局的,并且不断变化到新创建的实例。
3.开始时间变量是全局变量,每次调用renderTime函数时都会不断重置。
我已经在 jsFiddle 中对您的代码进行了修改,可以在本次更新中找到它们:http://jsfiddle.net/3qxoea52/5/
渲染:
this.renderTime = function (startTime) {
if( startTime ) {
this.startTime = startTime;
}
this.endTime = new Date();
// time difference in ms
this.timeDiff = this.endTime - this.startTime;
// strip the miliseconds
this.timeDiff /= 1000;
// get seconds
this.seconds = Math.round(this.timeDiff % 60);
// remove seconds from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get minutes
this.minutes = Math.round(this.timeDiff % 60);
// remove minutes from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get hours
this.hours = Math.round(this.timeDiff % 24);
this.block.innerHTML = this.hours + " h " + this.minutes + " min " + this.seconds + " sec";
// window.setInterval('this.obName.renderTime()',1000);// Uncomment if you want to test your PCs limit
}
绑定:
this.startButton.addEventListener("click", function () {
//if (this.hours === 0 && this.minutes === 0 && this.seconds === 0){
this.startTime = new Date();
// }
this.tm = window.setInterval(this.renderTime.bind(this), 1000);
}.bind(this))
this.stopButton.addEventListener("click", function () {
window.clearInterval(this.tm);
//timePassed = this.endTime - this.startTime;
//endTime = new Date();
// timePassed = endTime - startTime;
}.bind(this))
创建定时器:
function createNewTimer() {
obName = document.getElementById("ObName").value;
if (obName !== "") {
obName = new timerObject(obName);
obName.addBlock();
obName.renderButtons();
startTime = new Date();
obName.renderTime(startTime);
//window.setInterval('obName.renderTime()',1000);
} else {
document.getElementById("ObName").value = "Fill me";
}
};
我会尽可能简单地解释一下。
我正在尝试制作一个计时器应用程序来练习。用户应该能够添加一个新的对象,它将是一个计时器 + stop/start 个按钮。
此时,它正在处理一个对象,但是当我创建另一个对象时,旧对象停止工作(我相信它失去了指向它的指针,或类似的东西),而新对象开始工作。
别担心,关于按钮功能,这并不重要,我只想了解如何在创建新对象后保存对象。
这是 JS:
var startTime = 0;
var itemNum = 0;
var obName;
var arrayForTimers = [];
function timerObject(obName) {
this.nameField = "start";
this.classField = "timer";
this.block = " ";
this.obName = obName;
this.startButton = " ";
this.stopButton = " ";
this.placeholder = document.getElementsByClassName("timer-placeholder")[0];
this.addBlock = function () {
this.block = document.createElement("DIV");
this.block.className = this.classField;
this.block.className += " " + this.obName;
this.placeholder.appendChild(this.block);
}
this.renderTime = function () {
this.startTime = startTime;
this.endTime = new Date();
// time difference in ms
this.timeDiff = this.endTime - this.startTime;
// strip the miliseconds
this.timeDiff /= 1000;
// get seconds
this.seconds = Math.round(this.timeDiff % 60);
// remove seconds from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get minutes
this.minutes = Math.round(this.timeDiff % 60);
// remove minutes from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get hours
this.hours = Math.round(this.timeDiff % 24);
this.block.innerHTML = this.hours + " h " + this.minutes + " min " + this.seconds + " sec";
// window.setInterval('this.obName.renderTime()',1000);// Uncomment if you want to test your PCs limit
}
this.renderButtons = function () {
var timePassed;
//this.parentTimer = document.getElementsByClassName("timer "+this.obName)[0];
this.startButton = document.createElement("INPUT");
this.startButton.setAttribute("type", "button");
this.startButton.setAttribute("value", "start");
this.startButton.className = "start " + this.obName;
this.stopButton = document.createElement("INPUT");
this.stopButton.setAttribute("type", "button");
this.stopButton.setAttribute("value", "stop");
this.stopButton.className = "stop " + this.obName;
this.placeholder.insertBefore(this.startButton, this.block);
this.placeholder.insertBefore(this.stopButton, this.block);
this.startButton.addEventListener("click", function () {
//if (this.hours === 0 && this.minutes === 0 && this.seconds === 0){
this.startTime = new Date();
// }
tm = window.setInterval('obName.renderTime()', 1000);
})
this.stopButton.addEventListener("click", function () {
window.clearInterval(tm);
//timePassed = this.endTime - this.startTime;
//endTime = new Date();
// timePassed = endTime - startTime;
})
//give listener to clear and start interval
}
};
function createNewTimer() {
obName = document.getElementById("ObName").value;
if (obName !== "") {
obName = new timerObject(obName);
obName.addBlock();
obName.renderButtons();
startTime = new Date();
obName.renderTime();
//arrayForTimers.push(obName);
//window.setInterval('obName.renderTime()',1000);
} else {
document.getElementById("ObName").value = "Fill me";
}
};
这里有一个JsFiddlehttp://jsfiddle.net/3qxoea52/4/
P.S。对不起我的语法,不是我的母语。
谢谢。
问题就在这里
tm = window.setInterval('obName.renderTime()', 1000);
这意味着当您单击任何启动按钮时,它将始终启动当前与 obName 关联的对象。
此外,您只有一个全局变量 tm
来存储计时器,所以当您这样做时
window.clearInterval(tm);
正在清除上次设置的定时器。
而且您还有一个全局 startTime
,这会导致所有计时器在您创建新计时器时重置。
另一个问题是当你停止每个定时器时,你没有任何东西来存储时间,所以如果你停止然后重新启动它,它不会在同一点继续。
您可以通过以下方式解决这些问题:
- 使用
self = this
创建对象的稳定引用 - 使用
function.bind
确保事件处理程序将绑定到正确的计时器对象 - 添加一个属性
this.startDiff
以便在您停止然后重新启动时钟时保存时间 - 使
tm
成为TimerObject
中的局部变量
- 在对象内而不是在对象外设置
this.startTime
。
-- 如以下代码所示 (jsfiddle)
function TimerObject(obName) {
var self = this,
tm;
this.startTime = new Date();
this.startDiff = 0;
this.nameField = "start";
this.classField = "timer";
this.block = " ";
this.obName = obName;
this.startButton = " ";
this.stopButton = " ";
this.placeholder = document.getElementsByClassName("timer-placeholder")[0];
this.addBlock = function () {
this.block = document.createElement("DIV");
this.block.className = this.classField;
this.block.className += " " + this.obName;
this.placeholder.appendChild(this.block);
};
this.renderTime = function () {
var timeDiff = new Date() - this.startTime + this.startDiff;
this.timeDiff = timeDiff;
timeDiff /= 1000;
// get seconds
this.seconds = Math.round(timeDiff % 60);
// remove seconds from the date
timeDiff = Math.floor(timeDiff / 60);
// get minutes
this.minutes = Math.round(timeDiff % 60);
// remove minutes from the date
timeDiff = Math.floor(timeDiff / 60);
// get hours
this.hours = Math.round(timeDiff % 24);
this.block.innerHTML = this.hours + " h " + this.minutes + " min " + this.seconds + " sec";
// window.setInterval('this.obName.renderTime()',1000);// Uncomment if you want to test your PCs limit
};
this.renderButtons = function () {
var timePassed;
//this.parentTimer = document.getElementsByClassName("timer "+this.obName)[0];
this.startButton = document.createElement("INPUT");
this.startButton.setAttribute("type", "button");
this.startButton.setAttribute("value", "start");
this.startButton.className = "start " + this.obName;
this.stopButton = document.createElement("INPUT");
this.stopButton.setAttribute("type", "button");
this.stopButton.setAttribute("value", "stop");
this.stopButton.className = "stop " + this.obName;
this.placeholder.insertBefore(this.startButton, this.block);
this.placeholder.insertBefore(this.stopButton, this.block);
this.startButton.addEventListener("click", function () {
//if (this.hours === 0 && this.minutes === 0 && this.seconds === 0){
self.startTime = new Date();
// }
tm = window.setInterval(self.renderTime.bind(self), 1000);
});
this.stopButton.addEventListener("click", function () {
window.clearInterval(tm);
self.startDiff = self.timeDiff;
console.log(':', self, self.startDiff);
//timePassed = this.endTime - this.startTime;
//endTime = new Date();
// timePassed = endTime - startTime;
});
//give listener to clear and start interval
};
}
function createNewTimer() {
obName = document.getElementById("ObName").value;
if (obName !== "") {
obName = new TimerObject(obName);
obName.addBlock();
obName.renderButtons();
obName.renderTime();
//window.setInterval('obName.renderTime()',1000);
} else {
document.getElementById("ObName").value = "Fill me";
}
}
代码存在几个问题: 1. 一些函数没有绑定到正确的上下文 (this)。 2. 设置为 "obName" 的引用是全局的,并且不断变化到新创建的实例。 3.开始时间变量是全局变量,每次调用renderTime函数时都会不断重置。
我已经在 jsFiddle 中对您的代码进行了修改,可以在本次更新中找到它们:http://jsfiddle.net/3qxoea52/5/
渲染:
this.renderTime = function (startTime) {
if( startTime ) {
this.startTime = startTime;
}
this.endTime = new Date();
// time difference in ms
this.timeDiff = this.endTime - this.startTime;
// strip the miliseconds
this.timeDiff /= 1000;
// get seconds
this.seconds = Math.round(this.timeDiff % 60);
// remove seconds from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get minutes
this.minutes = Math.round(this.timeDiff % 60);
// remove minutes from the date
this.timeDiff = Math.floor(this.timeDiff / 60);
// get hours
this.hours = Math.round(this.timeDiff % 24);
this.block.innerHTML = this.hours + " h " + this.minutes + " min " + this.seconds + " sec";
// window.setInterval('this.obName.renderTime()',1000);// Uncomment if you want to test your PCs limit
}
绑定:
this.startButton.addEventListener("click", function () {
//if (this.hours === 0 && this.minutes === 0 && this.seconds === 0){
this.startTime = new Date();
// }
this.tm = window.setInterval(this.renderTime.bind(this), 1000);
}.bind(this))
this.stopButton.addEventListener("click", function () {
window.clearInterval(this.tm);
//timePassed = this.endTime - this.startTime;
//endTime = new Date();
// timePassed = endTime - startTime;
}.bind(this))
创建定时器:
function createNewTimer() {
obName = document.getElementById("ObName").value;
if (obName !== "") {
obName = new timerObject(obName);
obName.addBlock();
obName.renderButtons();
startTime = new Date();
obName.renderTime(startTime);
//window.setInterval('obName.renderTime()',1000);
} else {
document.getElementById("ObName").value = "Fill me";
}
};