对象构造函数内部的Javascript setInterval无法正常工作

马里奥斯·尼古拉(Marios Nikolaou)

我正在学习Javascript对象,但是我的代码有一个很奇怪的问题。以下代码使用来根据系统时间移动时钟小时,分,秒setInterval()我添加了一个开始和停止按钮来开始/停止时钟。但是,当我在runClock()内部运行时,interval它无法按预期运行。

当我将代码放置在setIntervallike中的匿名函数中时,它工作正常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>

欢迎任何意见。

nvkrj

setInterval()当你调用指定的功能无法正常工作this.runClock(),因为每次它被称为setInterval的时间,它接收的相同值hrminsec当这些值在函数内部递增(使时钟滴答)时,它们将无处保存,因为在函数执行时变量会丢失。然后,当函数被再次调用,它再次收到相同的值hrmin并且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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章