javascript - 创建新对象后,如何防止旧对象丢失?

标签 javascript oop date object timer

我会尝试尽可能简单地解释这一点。

我正在尝试制作一个计时器应用程序以供练习。用户应该能够添加一个新对象,它将是一个计时器+停止/启动按钮。

此时,它正在处理一个对象,但是当我创建另一个对象时,旧对象停止工作(我相信它丢失了指向它的指针,或类似的东西),而新对象则工作。

不用担心按钮功能,那并不重要,我只想了解创建新对象后如何保存对象。

这是 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 Fiddle http://jsfiddle.net/3qxoea52/4/

附注抱歉我的语法,不是我的母语。

谢谢。

最佳答案

问题就在这里

tm = window.setInterval('obName.renderTime()', 1000);

这意味着当您单击任何启动按钮时,它将始终启动当前与 obName 关联的对象。

此外,您只有一个全局变量tm来存储计时器,因此当您这样做时

window.clearInterval(tm);

它正在清除最后设置的计时器。

而且您还有一个全局 startTime,每当您创建新计时器时,它都会导致所有计时器重置。

另一个问题是,当你停止每个计时器时,你没有任何东西可以存储时间,所以如果你停止然后重新启动它,它不会在同一点继续。

您可以通过以下方式解决这些问题:

  1. 使用self = this创建对象的稳定引用
  2. 使用function.bind确保事件处理程序将绑定(bind)到正确的计时器对象
  3. 添加属性 this.startDiff,以便在停止然后重新启动时钟时保存时间
  4. 使 tm 成为 TimerObject 中的局部变量
  5. 在对象内部而不是外部设置 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";
    }
}

关于javascript - 创建新对象后,如何防止旧对象丢失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28915522/

相关文章:

javascript - 如何创建一个包含 3 个学生的数组并让他们按名字和 nid 排序

javascript - ExtJs 网格类似列创建更简单

javascript - Chrome(适用于 Android)媒体查询做错了?

c++ - 在函数中更改类实例的值

datetime - 使用相隔几秒的日期 - datenum 返回完全相同的值。我究竟做错了什么?

javascript - 如何同时异步触发多个 API 调用?

javascript - JS原型(prototype),小困惑

swift 3 : The difference between Public and Internal access modifiers?

mysql - 如何在 mysql 中获取最近 6 个月的详细信息

java - 日期 d = 新日期(0L); 0L在这个日期是什么意思?