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

How do I prevent loss of older objects, after I create a new one?

本文关键字:对象 何防止 新对象 创建      更新时间:2023-09-26

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,这会导致所有计时器在您创建新计时器时重置。

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

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

  1. 使用 self = this 创建对对象的稳定引用
  2. 使用 function.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";
    }
}

代码存在几个问题: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";
    }
};