Javascript 两个问题:this.myMethod不是由addEventListner添加的函数单击事件,当用户单击时会运行超过20次

Javascript 两个问题:this.myMethod不是由addEventListner添加的函数单击事件,当用户单击时会运行超过20次,javascript,timer,vue.js,vuejs2,Javascript,Timer,Vue.js,Vuejs2,我试图用vue.js制作一个计时器,但遇到了一些问题。这是我的mtehods部分: methods: { saveRunningMethod() { var runningData = { duration: `${this.hour} : ${this.minute} : ${this.second}`, username: this.$store.state.user.username

我试图用vue.js制作一个计时器,但遇到了一些问题。这是我的mtehods部分:

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);

    }
}
谢谢。

,这就是
window.setInterval()所做的:

重复调用函数,每次调用该函数之间有固定的时间延迟

因此,当执行
startTimer()
方法时,它每100毫秒向停止按钮添加一个
click
事件侦听器。因此,如果加载页面并等待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秒,则
单击
事件侦听器将被添加到按钮54次

您应该使用
window.setTimeout()
,而不是使用
window.setInterval()
,这就是它所做的:

在指定延迟后执行代码段或函数

换句话说,
window.setTimeout()
创建一个计时器,该计时器在指定的延迟后只运行一次

至于
this.saveRunningMethod()不是函数的错误
,您的上下文在传递给
addEventListener()
的回调函数中发生了变化,因此
this
的值成为按钮本身,而不是对象。为了避免这种情况,可以将一个箭头函数传递给
addEventListener()
。这将导致上下文保持不变(因此在arrow函数中,
This
的值将保持您的对象):


从您的代码不清楚,为什么定时器运行多次。编辑问题并添加HTML部分。@WaldemarIce我的HTML部分只是一个div,显示计时器和两个按钮,我更新问题并添加它。谢谢。请一次问一个问题@EmadDehnavi尝试,作为快速修复,将启动计时器定义为箭头函数。只需将第一行更改为以下语法:
startTimer:\u=>{
@Rob抱歉,因为两者都与同一代码相关,我只是在一个问题中问了他们,下次注意,谢谢。谢谢你的回答,它解释了一切,我想我需要找到另一种方法来创建计时器,因为setTimeout和setInterval都无法实现计时器。另外,还向addEventListener()添加了箭头函数修正了我第二个问题的问题。
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)
window.setTimeout(() => {
    var e = document.getElementById("stopBtn")
    e.addEventListener("click", () => {
        this.isTimerStart = false;
        console.log("lets Save it");
        this.saveRunningMethod();
    });
}, 100)