从同一对象的不同实例中触发另一个实例的函数

时间:2018-01-02 12:04:42

标签: javascript timer

我是Javascript的初学者,我正在努力弄清楚如何使用一个实例的函数来触发另一个实例中的函数,反之亦然,这两个类都是同一个类。让我解释一下我的意思。

我的项目是用Javascript构建一个番茄钟。番茄钟是一个你在指定时间内工作的过程(例如25分钟),然后短暂休息(5分钟),然后重复。时钟应该无限期地运行,或者直到用户停止它为止。

我需要完成一个时钟来触发另一个时钟的开始,反之亦然。

我为每个计时器使用完全独立的,略有不同的功能构建了一个工作程序(冗余很多)。我试图通过创建一类Timers并从中构建每一个来简化我的代码。那就是我被困住的地方。

我的Timer类中有一个函数,当计时器到达零时,需要调用另一个计时器的倒计时开始(Codepen上的第126行)。我怎么能这样做?

感谢您提供任何帮助。

这是我在Codepen上的项目:https://codepen.io/lieberscott/pen/baRpgx?editors=1010

我的Javascript代码如下:

let session; // session Timer object instance
let btimer; // break Timer object instance

let s_off; // boolean for whether session timer is off or on
let s_timer; // reference to session timer HTML element
let s_stop; // reference to session stop HTML button
let s_increase; // reference to session increase HTML button
let s_decrease; // reference to session decrease HTML button

// same variables as above for break timer
let b_off;
let b_timer;
let b_stop;
let b_increase;
let b_decrease;


$(document).ready(function() {
  s_off = true;
  s_timer = $("#timer");
  s_stop = $("#stop");
  s_increase = $("#increase");
  s_decrease = $("#decrease");
  b_off = true;
  b_timer = $("#breaktimer");
  b_stop = $("#breakstop");
  b_increase = $("#breakincrease");
  b_decrease = $("#breakdecrease");

  session = new Timer(1, 60, s_off, s_timer, s_stop, s_increase, s_decrease);
  btimer = new Timer(5, 60, b_off, b_timer, b_stop, b_increase, b_decrease);

  // increase session minutes
  $(s_increase).on("click", function() {
    if (session.off) {
      session.min++;
      session.sec = 00;
      s_timer.html(session.min + ":" + session.sec);
    }
  });

  // decrease session minutes
  $(s_decrease).on("click", function() {
    if (session.off) {
      if (session.min > 1) {
        session.min--;
      }
      session.sec = 00;
      s_timer.html(session.min + ":" + session.sec);
    }
  });

  // increase break minutes
  $(b_increase).on("click", function() {
    if (btimer.off) {
      btimer.min++;
      btimer.sec = 00;
      b_timer.html(btimer.min + ":" + btimer.sec);
    }
  });

  // decrease break minutes
  $(b_decrease).on("click", function() {
    if (btimer.off) {
      if (btimer.min > 1) {
        btimer.min--;
      }
      btimer.sec = 00;
      b_timer.html(btimer.min + ":" + btimer.sec);
    }
  });

  // begin session timer by clicking on the timer itself
  $(s_timer).on("click", function() {
    session.time();
  });

  // stop session timer
  $(s_stop).on("click", function() {
    session.off = true;
    session.stopClock(session.intervalFunction);
  });

  // stop break timer
  $(b_stop).on("click", function() {
    btimer.off = true;
    btimer.stopClock(btimer.intervalFunction);
  });

});


class Timer {
  constructor(min, sec, off, disp, stopButton, increaseButton, decreaseButton) {
    this.min = min; // minutes
    this.minsSet = min; // minutes again, this will be used to reset the timer
    this.sec = sec;
    this.off = off; // boolean saying whether timer is off or not
    this.disp = disp; // HTML display
    this.stopButton = stopButton;
    this.increaseButton = increaseButton;
    this.decreaseButton = decreaseButton;
    this.func;
  }

  time() { // function fired when the timer is clicked
    if (this.off) {
      this.off = false;
      this.func = this.intervalFunc();
    }
  }

  intervalFunc() { // set the interval of the timer
    setInterval(function() {this.countdown();}, 1000); // ERROR HERE
  }

  countdown() { // interval to complete for duration of timer
    // check if clock reaches zero
    if (this.sec == 0) {
      this.min--;
      this.sec = 60;
      if (this.min < 0) {
        this.min = this.minsSet;
        this.sec = 0;
        this.off = true;
        this.time(); // this needs to trigger, not this.time(), but the OTHER object's time() function
        this.stopClock(this.func); // clearInterval() function below
      }
    }

    // if clock is not at 0:00, display new time
    this.sec--;
    let m = this.min.toString();
    let s;
    if (this.sec < 10) {
      s = "0" + this.sec.toString()
    }
    else {
      s = this.sec.toString();
    }
    this.disp.html(m + ":" + s);
  }

  stopClock() {
    clearInterval(this.func);
  }
}

2 个答案:

答案 0 :(得分:1)

1)我尝试了你的代码并修复了一些错误,你的setInterval问题是因为&#34;这个&#34;指向那里的窗口对象。

2)为了调用另一个对象time()方法,首先你需要知道你正在使用哪个对象,所以我在类中添加了一个类型变量,然后在倒计时函数中添加了一个检查。 更改在此笔中:

https://codepen.io/yaduvanshi/pen/dJRdeR?editors=0010

intervalFunc() { // set the interval of the timer
   var that =this;
   setInterval(function() {that.countdown();}, 1000); // ERROR HERE
}

答案 1 :(得分:0)

我认为您正在寻找的解决方案是Javascript为您提供的.bind()或.call()(Function.prototype.bind())。例如,.bind()函数将特定对象实例作为参数。你可以在这里阅读相同内容 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind