同一页上的两个相同 javascript class 的实例指的是同一个实例
Two instances of same javascript class on one page refer to same instance
我正在尝试编写一个倒计时计时器脚本,它只适用于页面上的一个实例,但如果我添加第二个实例,则只有第二个实例开始计数。
我发现如果我加载两个,但只为第二个调用启动,第一个就会触发。看起来它们的范围不正确。
我正在使用新的 class 语法,所以我认为它应该可以正常工作,但我显然遗漏了一些东西。我希望有人能帮助我理解我做错了什么。我的主要语言是 PHP,我并不像我希望的那样精通 JS。
这是我要点的 link,其中包含代码:https://gist.github.com/kennyray/b35f4c6640be9539c5d16581de7714e0
class CountdownTimer {
constructor(minutesLabel = null, secondsLabel = null) {
self = this;
this.minutesLabel = minutesLabel;
this.secondsLabel = secondsLabel;
this.totalSeconds = (this.minutesLabel.textContent / 60) + this.secondsLabel.textContent;
this.timer = null;
}
set minutesLabel(value) {
self._minutesLabel = value;
}
set secondsLabel(value) {
self._secondsLabel = value;
}
get minutesLabel() {
return self._minutesLabel;
}
get secondsLabel() {
return self._secondsLabel;
}
setTime() {
self.totalSeconds--;
if (parseInt(self.minutesLabel.innerHTML) == 0 && parseInt(self.secondsLabel.innerHTML) == 0) { self.stopTimer; return;}
if (self.secondsLabel.innerHTML.textContent < 0) { self.secondsLabel.innerHTML = 59 }
if (self.minutesLabel.innerHTML.textContent < 0) { self.minutesLabel.innerHTML = 59 }
self.secondsLabel.innerHTML = self.pad((self.totalSeconds % 60));
self.minutesLabel.innerHTML = self.pad(Math.floor(self.totalSeconds / 60));
}
pad(val) {
var valString = val + "";
if (valString.length < 2) {
return "0" + valString;
} else {
return valString;
}
}
resetTimer() {
clearInterval(self.timer);
self.totalSeconds = 0;
self.secondsLabel.innerHTML = self.pad(self.totalSeconds % 60);
self.minutesLabel.innerHTML = self.pad(parseInt(self.totalSeconds / 60));
}
startTimer() {
self.timer = setInterval(self.setTime, 1000);
}
stopTimer() {
clearInterval(self.timer);
}
}
const t1 = new CountdownTimer(document.getElementById("minutes1"), document.getElementById("seconds1"));
t1.startTimer();
const t2 = new CountdownTimer(document.getElementById("minutes"), document.getElementById("seconds"));
console.log(t1.startTimer() === t2.startTimer());
t2.startTimer();
<label id="minutes1">01</label>:<label id="seconds1">10</label>
<br>
<label id="minutes">00</label>:<label id="seconds">10</label>
你正在声明一个全局变量 self
(你到底为什么要这样做?),它被覆盖了。只需在 class.
中使用 this
然后您的 startTimer 函数需要
startTimer() {
this.timer = setInterval(this.setTime.bind(this), 1000);
}
并且也许应该检查是否已经存在间隔并完全清除 this.timer
startTimer() {
if (this.timer) this.stopTimer();
this.timer = setInterval(this.setTime.bind(this), 1000);
}
stopTimer() {
clearInterval(this.timer);
this.timer = null;
}
归根结底就是这一行
self = this;
通过不包括关键字 var
,您将其提升到全局范围。如果你想在 ctor 中使用 self
而不是 this
(这很好)只需在它的前面加上 var
:
var self = this;
我正在尝试编写一个倒计时计时器脚本,它只适用于页面上的一个实例,但如果我添加第二个实例,则只有第二个实例开始计数。
我发现如果我加载两个,但只为第二个调用启动,第一个就会触发。看起来它们的范围不正确。
我正在使用新的 class 语法,所以我认为它应该可以正常工作,但我显然遗漏了一些东西。我希望有人能帮助我理解我做错了什么。我的主要语言是 PHP,我并不像我希望的那样精通 JS。
这是我要点的 link,其中包含代码:https://gist.github.com/kennyray/b35f4c6640be9539c5d16581de7714e0
class CountdownTimer {
constructor(minutesLabel = null, secondsLabel = null) {
self = this;
this.minutesLabel = minutesLabel;
this.secondsLabel = secondsLabel;
this.totalSeconds = (this.minutesLabel.textContent / 60) + this.secondsLabel.textContent;
this.timer = null;
}
set minutesLabel(value) {
self._minutesLabel = value;
}
set secondsLabel(value) {
self._secondsLabel = value;
}
get minutesLabel() {
return self._minutesLabel;
}
get secondsLabel() {
return self._secondsLabel;
}
setTime() {
self.totalSeconds--;
if (parseInt(self.minutesLabel.innerHTML) == 0 && parseInt(self.secondsLabel.innerHTML) == 0) { self.stopTimer; return;}
if (self.secondsLabel.innerHTML.textContent < 0) { self.secondsLabel.innerHTML = 59 }
if (self.minutesLabel.innerHTML.textContent < 0) { self.minutesLabel.innerHTML = 59 }
self.secondsLabel.innerHTML = self.pad((self.totalSeconds % 60));
self.minutesLabel.innerHTML = self.pad(Math.floor(self.totalSeconds / 60));
}
pad(val) {
var valString = val + "";
if (valString.length < 2) {
return "0" + valString;
} else {
return valString;
}
}
resetTimer() {
clearInterval(self.timer);
self.totalSeconds = 0;
self.secondsLabel.innerHTML = self.pad(self.totalSeconds % 60);
self.minutesLabel.innerHTML = self.pad(parseInt(self.totalSeconds / 60));
}
startTimer() {
self.timer = setInterval(self.setTime, 1000);
}
stopTimer() {
clearInterval(self.timer);
}
}
const t1 = new CountdownTimer(document.getElementById("minutes1"), document.getElementById("seconds1"));
t1.startTimer();
const t2 = new CountdownTimer(document.getElementById("minutes"), document.getElementById("seconds"));
console.log(t1.startTimer() === t2.startTimer());
t2.startTimer();
<label id="minutes1">01</label>:<label id="seconds1">10</label>
<br>
<label id="minutes">00</label>:<label id="seconds">10</label>
你正在声明一个全局变量 self
(你到底为什么要这样做?),它被覆盖了。只需在 class.
this
然后您的 startTimer 函数需要
startTimer() {
this.timer = setInterval(this.setTime.bind(this), 1000);
}
并且也许应该检查是否已经存在间隔并完全清除 this.timer
startTimer() {
if (this.timer) this.stopTimer();
this.timer = setInterval(this.setTime.bind(this), 1000);
}
stopTimer() {
clearInterval(this.timer);
this.timer = null;
}
归根结底就是这一行
self = this;
通过不包括关键字 var
,您将其提升到全局范围。如果你想在 ctor 中使用 self
而不是 this
(这很好)只需在它的前面加上 var
:
var self = this;