我正在学习Javascript对象,但是我的代码有一个很奇怪的问题。以下代码使用来根据系统时间移动时钟小时,分,秒setInterval()
。我添加了一个开始和停止按钮来开始/停止时钟。但是,当我在runClock()
内部运行时,interval
它无法按预期运行。
当我将代码放置在setInterval
like中的匿名函数中时,它工作正常setInterval(function(){ ... },1000)
。
const HOURHAND = document.querySelector("#hour");
const MINUTEHAND = document.querySelector("#minute");
const SECONDHAND = document.querySelector("#second");
function TimerInit(){
this.timer = null;
this.startBtn = document.querySelector('#startBtn');
this.stopBtn = document.querySelector('#stopBtn');
this.init = function(){
const dt = new Date();
console.log(`Hours: ${dt.getHours()} min: ${dt.getMinutes()} sec: ${dt.getSeconds()}`);
let hr = dt.getHours();
let min = dt.getMinutes();
let sec = dt.getSeconds();
let hourDeg = (hr * 360 / 12) + (min * (36/60) / 12);
let minDeg = (min * 360 / 60) + (sec * (36/60) / 60);
let secDeg = sec * 360 / 60;
return { hr:hourDeg, min:minDeg, sec:secDeg };
};
this.startBtn.onclick = function(){
let { hr, min, sec } = this.init();
console.log(`${hr} ${min} ${sec}`);
this.timer = setInterval(this.runClock.bind(this, hr, min, sec), 1000);
//the code below works
/*this.timer = setInterval(()=>{
hr += (3/360);
min += (6/60);
sec += 6;
console.log(`${hr} ${min} ${sec}`);
HOURHAND.style.transform = `rotate(${hr}deg)`;
MINUTEHAND.style.transform = `rotate(${min}deg)`;
SECONDHAND.style.transform = `rotate(${sec}deg)`;
},1000);*/
}.bind(this);
this.runClock = function(hr,min,sec){
hr += (3/360);
min += (6/60);
sec += 6;
//console.log(`${hr} ${min} ${sec}`);
HOURHAND.style.transform = `rotate(${hr}deg)`;
MINUTEHAND.style.transform = `rotate(${min}deg)`;
SECONDHAND.style.transform = `rotate(${sec}deg)`;
}
this.stopBtn.onclick = function(){
clearInterval(this.timer);
}.bind(this);
}
const obj = new TimerInit();
/* Layout */
.main {
display: flex;
padding: 2em;
height: 90vh;
justify-content: center;
align-items: middle;
}
.clockbox,
#clock {
width: 100%;
}
/* Clock styles */
.circle {
fill: none;
stroke: #000;
stroke-width: 9;
stroke-miterlimit: 10;
}
.mid-circle {
fill: #000;
}
.hour-marks {
fill: none;
stroke: #000;
stroke-width: 9;
stroke-miterlimit: 10;
}
.hour-arm {
fill: none;
stroke: #000;
stroke-width: 17;
stroke-miterlimit: 10;
}
.minute-arm {
fill: none;
stroke: #000;
stroke-width: 11;
stroke-miterlimit: 10;
}
.second-arm {
fill: none;
stroke: #000;
stroke-width: 4;
stroke-miterlimit: 10;
}
/* Transparent box ensuring arms center properly. */
.sizing-box {
fill: none;
}
/* Make all arms rotate around the same center point. */
/* Optional: Use transition for animation. */
#hour,
#minute,
#second {
transform-origin: 300px 300px;
transition: transform .5s ease-in-out;
}
<main class="main">
<div class="clockbox">
<svg id="clock" xmlns="http://www.w3.org/2000/svg" width="600" height="600" viewBox="0 0 600 600">
<g id="face">
<circle class="circle" cx="300" cy="300" r="253.9"/>
<path class="hour-marks" d="M300.5 94V61M506 300.5h32M300.5 506v33M94 300.5H60M411.3 107.8l7.9-13.8M493 190.2l13-7.4M492.1 411.4l16.5 9.5M411 492.3l8.9 15.3M189 492.3l-9.2 15.9M107.7 411L93 419.5M107.5 189.3l-17.1-9.9M188.1 108.2l-9-15.6"/>
<circle class="mid-circle" cx="300" cy="300" r="16.2"/>
</g>
<g id="hour">
<path class="hour-arm" d="M300.5 298V142"/>
<circle class="sizing-box" cx="300" cy="300" r="253.9"/>
</g>
<g id="minute">
<path class="minute-arm" d="M300.5 298V67"/>
<circle class="sizing-box" cx="300" cy="300" r="253.9"/>
</g>
<g id="second">
<path class="second-arm" d="M300.5 350V55"/>
<circle class="sizing-box" cx="300" cy="300" r="253.9"/>
</g>
</svg>
</div><!-- .clockbox -->
</main>
<button id="startBtn">Start</button>
<button id="stopBtn">Stop</button>
欢迎任何意见。
setInterval()
当你调用指定的功能无法正常工作this.runClock()
,因为每次它被称为setInterval的时间,它接收的相同值hr
,min
和sec
。当这些值在函数内部递增(使时钟滴答)时,它们将无处保存,因为在函数执行时变量会丢失。然后,当函数被再次调用,它再次收到相同的值hr
,min
并且sec
它收到第一次执行时。这样,时钟就不起作用了。
这是因为runClock不会维护对象的状态。相反,您可以将这些值保存在对象的状态本身中,然后直接在中使用它们runClock()
。这样,每次增加它们时,该增加的值将被保存。
const HOURHAND = document.querySelector("#hour");
const MINUTEHAND = document.querySelector("#minute");
const SECONDHAND = document.querySelector("#second");
function TimerInit(){
this.timer = null;
this.startBtn = document.querySelector('#startBtn');
this.stopBtn = document.querySelector('#stopBtn');
this.init = function(){
const dt = new Date();
console.log(`Hours: ${dt.getHours()} min: ${dt.getMinutes()} sec: ${dt.getSeconds()}`);
let hr = dt.getHours();
let min = dt.getMinutes();
let sec = dt.getSeconds();
this.hourDeg = (hr * 360 / 12) + (min * (36/60) / 12);
this.minDeg = (min * 360 / 60) + (sec * (36/60) / 60);
this.secDeg = sec * 360 / 60;
};
this.startBtn.onclick = function(){
this.init();
this.timer = setInterval(this.runClock.bind(this), 1000);
}.bind(this);
this.runClock = function(){
this.hourDeg += (3/360);
this.minDeg += (6/60);
this.secDeg += 6;
console.log(`${this.hourDeg} ${this.minDeg} ${this.secDeg}`);
HOURHAND.style.transform = `rotate(${this.hourDeg}deg)`;
MINUTEHAND.style.transform = `rotate(${this.minDeg}deg)`;
SECONDHAND.style.transform = `rotate(${this.secDeg}deg)`;
}
this.stopBtn.onclick = function(){
clearInterval(this.timer);
}.bind(this);
}
const obj = new TimerInit();
/* Layout */
.main {
display: flex;
padding: 2em;
height: 90vh;
justify-content: center;
align-items: middle;
}
.clockbox,
#clock {
width: 100%;
}
/* Clock styles */
.circle {
fill: none;
stroke: #000;
stroke-width: 9;
stroke-miterlimit: 10;
}
.mid-circle {
fill: #000;
}
.hour-marks {
fill: none;
stroke: #000;
stroke-width: 9;
stroke-miterlimit: 10;
}
.hour-arm {
fill: none;
stroke: #000;
stroke-width: 17;
stroke-miterlimit: 10;
}
.minute-arm {
fill: none;
stroke: #000;
stroke-width: 11;
stroke-miterlimit: 10;
}
.second-arm {
fill: none;
stroke: #000;
stroke-width: 4;
stroke-miterlimit: 10;
}
/* Transparent box ensuring arms center properly. */
.sizing-box {
fill: none;
}
/* Make all arms rotate around the same center point. */
/* Optional: Use transition for animation. */
#hour,
#minute,
#second {
transform-origin: 300px 300px;
transition: transform .5s ease-in-out;
}
<main class="main">
<div class="clockbox">
<svg id="clock" xmlns="http://www.w3.org/2000/svg" width="600" height="600" viewBox="0 0 600 600">
<g id="face">
<circle class="circle" cx="300" cy="300" r="253.9"/>
<path class="hour-marks" d="M300.5 94V61M506 300.5h32M300.5 506v33M94 300.5H60M411.3 107.8l7.9-13.8M493 190.2l13-7.4M492.1 411.4l16.5 9.5M411 492.3l8.9 15.3M189 492.3l-9.2 15.9M107.7 411L93 419.5M107.5 189.3l-17.1-9.9M188.1 108.2l-9-15.6"/>
<circle class="mid-circle" cx="300" cy="300" r="16.2"/>
</g>
<g id="hour">
<path class="hour-arm" d="M300.5 298V142"/>
<circle class="sizing-box" cx="300" cy="300" r="253.9"/>
</g>
<g id="minute">
<path class="minute-arm" d="M300.5 298V67"/>
<circle class="sizing-box" cx="300" cy="300" r="253.9"/>
</g>
<g id="second">
<path class="second-arm" d="M300.5 350V55"/>
<circle class="sizing-box" cx="300" cy="300" r="253.9"/>
</g>
</svg>
</div><!-- .clockbox -->
</main>
<button id="startBtn">Start</button>
<button id="stopBtn">Stop</button>
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句