2017-11-11 74 views
0

我試圖用vue.js製作一個計時器,但我遇到了一些問題。這是我的mtehods部分:兩個問題:this.myMethod不是一個函數 - addEventListner添加的點擊事件在用戶點擊時運行多於20次

methods: {   
    saveRunningMethod() { 
     var runningData = { 
      duration: `${this.hour} : ${this.minute} : ${this.second}`, 
      username: this.$store.state.user.username 
     } 
     this.$store.dispatch('saveRunning' , runningData) 
     console.log(runningData); 
    }, 
    startTimer(){  
     this.isTimerStart = true; 
     var timer = window.setInterval(() => { 

      var e = document.getElementById("stopBtn") 
      e.addEventListener("click", function(){ 
       clearInterval(timer) 
       this.isTimerStart = false; 
       console.log("lets Save it") 
       this.saveRunningMethod() 
       }); 

      if(this.mSecond < 9) 
       this.mSecond +=1 
      else 
       this.mSecond=0 

      if(this.mSecond==9) 
       this.second +=1     

      if(this.second>59)     
       this.second=0 

      if(this.second==59) 
       this.minute +=1 

      if(this.minute>59) 
       this.minute = 0 

      if(this.minute==59) 
       this.hour +=1    

    },100); 

    } 
} 

在這裏,我e.addEventListener("click", function(){會停止計時器,當我點擊我的停止按鈕,但似乎這個方法運行多時間,因爲你在這張圖片上看到的,我的console.log運行33次!這是爲什麼?

enter image description here

我的其他問題,是關於這一行:this.saveRunningMethod()我跑我startTimer()方法中這種方法,但我得到"this.saveRunningMethod() is not a function"錯誤!

最後,你可以看到我用setInterval來製作一個計時器,如果你知道一個更好的解決方案,我會非常感激。

UPDATE:我補充我的html部分

<div class="row p-2 m-3 mt-3"> 
     <div class="col-12 p-0 animated fadeInUp mt-3"> 
      <p class="text-center">Your last record was : 00:00:00</p> 
     </div> 
     <div class="col-12 p-0 animated fadeInUp mt-3"> 
      <h1 class="text-center timer"> 
       {{this.hour}}:{{this.minute}}:{{second}}:{{mSecond}} 
      </h1> 
     </div> 
    </div> 
    <div class="row p-2 mt-3" v-bind:class="[this.isTimerStart==false ? 'show' : 'hide']"> 
     <div class="col-12 p-0 animated tada text-center"> 
      <button class="btn-link timerImg" @click="startTimer()"> 
       <img class="img-fluid timerImg" src="../../static/timerStart.png" /> 
       <p>Start</p> 
      </button> 
     </div> 
    </div> 

    <div class="row p-2 mt-3" v-bind:class="[this.isTimerStart ? 'show' : 'hide']"> 
     <div class="col-12 p-0 animated tada text-center"> 
      <button id="stopBtn" class="btn-link timerImg"> 
       <img class="img-fluid timerImg" src="../../static/timerStop.png" /> 
       <p>Stop</p> 
      </button> 
     </div> 
    </div> 

謝謝。

+0

從你的代碼是不明確的,爲什麼是定時器運行的多發時期。編輯問題並添加HTML部分。 – WaldemarIce

+0

@WaldemarIce我的html部分只是一個顯示計時器和兩個按鈕的div,我更新了問題並添加了它。謝謝。 –

+0

請一次提出一個問題。 https://stackoverflow.com/help/how-to-ask – Rob

回答

1

According to MDN,這是window.setInterval()做:

重複調用的函數,每次調用該函數之間的固定時間延遲。

所以執行您的startTimer()方法時,它被添加click事件監聽到你停止按鈕每100毫秒。所以,如果你加載頁面,點擊停止按鈕之前等待3.3秒,該click事件監聽器將被添加到按鈕33倍:

var timer = window.setInterval(() => { 

    var e = document.getElementById("stopBtn") 
    e.addEventListener("click", function() { 
     // This code will execute 33 times when the stop button is clicked. 
    }) 
    ... 
}, 100) 

如果您加載網頁並等待5.4秒單擊停止前按鈕,click事件監聽器將被添加到按鈕54次!

而不是使用window.setInterval()你應該使用window.setTimeout()According to MDN,這是它的作用:

在指定的延遲後執行代碼段或函數。

換句話說,window.setTimeout()會創建一個計時器,該計時器只能在您指定的延遲後運行一次。

至於錯誤this.saveRunningMethod() is not a function,你的上下文傳遞給addEventListener()的回調函數內改變,所以this值變爲按鈕本身,而不是你的對象。爲了避免這種情況,您可以將箭頭函數傳遞給addEventListener()。這將使得環境保持不變(所以箭頭函數內部的this值將保持你的對象):

window.setTimeout(() => { 
    var e = document.getElementById("stopBtn") 
    e.addEventListener("click",() => { 
     this.isTimerStart = false; 
     console.log("lets Save it"); 
     this.saveRunningMethod(); 
    }); 
}, 100) 
+0

感謝您的回答,它解釋了一切,我想我需要找到另一種方法來創建一個計時器,因爲setTimeout無法通過setInterval實現。同時將箭頭函數添加到addEventListener()解決了我的第二個問題。 –

相關問題