创建新对象后,如何防止丢失旧对象
How do I prevent loss of older objects, after I create a new one?
Il 尽量简单地解释这一点。
我正在尝试制作一个用于练习的计时器应用程序。用户应该可以添加新对象,这将是一个计时器+停止/启动按钮。
在这一点上,它与一个对象一起工作,但是当我创建另一个对象时,旧的对象停止工作(我相信它丢失了指向它的指针,或类似的东西),而新对象工作。
别担心,关于按钮功能,这并不重要,我只想了解在创建新对象后如何保存对象。
这是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";
}
};
这是一个 Js 小提琴 http://jsfiddle.net/3qxoea52/4/
附言对不起我的语法,而不是我的母语。
谢谢。
问题就在这里
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. 某些函数未绑定到正确的上下文(此)。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";
}
};
相关文章:
- 如何防止sails.js在所有视图中传递req对象
- 如何防止范围对象被更改
- 如何防止bind在使用async.series时更改node.js中的原始对象
- 创建新对象后,如何防止丢失旧对象
- 防止可拖动对象被添加多次jQuery
- Meteor模板数据对象可防止javascript事件触发
- XUL文档与HTML文档对象有何不同
- 在javascript(three.js)中使用函数:.load()后,如何防止对象被破坏
- Javascript对象:这两个值有何不同
- 什么是声明性环境记录,它与激活对象有何不同
- javascript删除对象,防止内存泄漏
- 在比较和匹配两个对象列表时,防止结果列表中重复
- JQuery 可拖动 - 防止网格对象移动到同一位置
- 在后台发生什么,以防止调用更改此对象的绑定方法
- 将单选按钮绑定到复杂对象可防止选中
- 防止对象数组中出现重复项
- 如何防止对象/数组突变
- 如何防止机器人的新对象与以前的机器人移动到相同的位置
- JS:防止访问未定义对象的属性时出错
- 如何在对对象进行字符串化时防止对数字进行字符串化