setInterval()添加类,然后删除类相同的时间 [英] setInterval() to add class then remove class for same amount of time

查看:72
本文介绍了setInterval()添加类,然后删除类相同的时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个简单的西蒙游戏".目前,我一直试图在div上添加一个"on"类一秒钟,然后在相同的时间内删除该类.

I am trying to make a simple 'Simon Game'. I am currently stuck trying to add a class 'on' to a div for one second, then remove that class for the same amount of time.

所以我有四个div,根据数字序列(例如, [0, 1, 2, 3].这将使div[0]闪烁1秒钟,然后闪烁1秒钟,然后移动到div[1],打开和关闭,依此类推.

So I have four divs that I am blinking on and off depending on a sequence of numbers, e.g. [0, 1, 2, 3]. This would blink div[0] on for one second and off for one second then move to div[1], on and off and so on.

这是我的职责

/**
 * sequence => array [0, 1, 2, 3]
 * speed    => int 1000 (one second)
 */
playSequence: function(sequence, speed){
    var self = this;

    // removes class 'on'
    view.turnOffPads();
    setTimeout(function(){
        // adds the 'on' class to a specific div
        view.lightUpPad(model.startupSequence[model.count]);
    }, speed / 2);

    setTimeout(function(){
        model.count++; // keeps track of the iterations
        if (model.count < sequence.length) { // if we are still iterating
            self.playSequence(sequence, speed); // light up the next div
        } else {
            model.count = 0; // set back to zero
        }
    }, speed);
},

问题是我正在互相使用两个setTimeout函数,尽管它起作用了,但我想知道是否有更好的方法.如果您看的话,我在模型对象中使用了一个count变量来跟踪迭代.

The problem with this is that I am using two setTimeout functions with one another and although it works I am wondering if there is a better way. If you look I am using a count variable in my model object to keep track of iterations.

这是到目前为止我完整的javascript应用...

Here is my full javascript app so far...

$(function(){

    var model = {
        on: false,
        strictMode: false,
        startupSequence: [0, 1, 2, 3, 3, 3, 2, 1, 0, 3, 2, 1, 0, 2, 1, 3],
        score: 0,
        sequence: [],
        count: 0,
    }

    var controller = {
        init: function(){
            view.cacheDOM();
            view.bindEvents();
        },
        getSequence: function(){
            // get a random number from one to 4
            var random = Math.floor(Math.random() * 4);
            // push it to the sequence array
            model.sequence.push(random);
            console.log(model.sequence);
            // play it
            this.playSequence(model.sequence);
        },

        /**
         * sequence => array [0, 1, 2, 3]
         * speed    => int 1000 (one second)
         */
        playSequence: function(sequence, speed){
            console.log(sequence.length);
            var self = this;

            view.turnOffPads();
            setTimeout(function(){
                view.lightUpPad(model.startupSequence[model.count]);
            }, speed / 2);

            setTimeout(function(){
                model.count++;
                if (model.count < sequence.length) {
                    self.playSequence(sequence, speed);
                } else {
                    model.count = 0;
                }
            }, speed);
            // view.turnOffPads();
        },
    }

    var view = {
        cacheDOM: function(){
            this.$round  = $('#round');
            this.$start  = $('#start');
            this.$strict = $('#strict');
            this.$pad    = $('.pad');

            this.$padArray = document.getElementsByClassName('pad');
        },
        bindEvents: function(){
            this.$start .change(this.start.bind(this));
            this.$strict.change(this.setStrictMode.bind(this));
        },
        start: function(){
            // turn on pads
            if (model.on) {
                this.$pad.removeClass('on');
                this.$round.text('--');
                model.on = false;
                // reset everything
            } else {
                this.$round.text(model.score);
                model.on = true;
                controller.playSequence(model.startupSequence, 100)
                // controller.getSequence();
            }
        },
        lightUpPad: function(i){
            $(this.$padArray[i]).addClass('on');
        },
        turnOffPads: function(){
            this.$pad.removeClass('on');
        },
        setStrictMode: function(){
            if (model.strictMode) {
                model.strictMode = false;
            } else {
                model.strictMode = true;
            }
        }
    }

    controller.init();
});

有没有更干净的方法来添加课程,然后删除课程?

Is there a cleaner way to add a class, and then remove a class?

推荐答案

我认为您可以将按钮列表变成一系列命令.然后,您可以使用单个setInterval播放命令,直到命令用尽. setInterval如果希望打开和关闭的时间一样长,则可以使用1秒的间隔,但也可以将其设置为更快一点,以轻松地允许不同的持续时间.

I think you could turn a list of buttons into a sequence of commands. Then you could use a single setInterval to play commands until it runs out of commands. The setInterval could use 1 second intervals if you want on and off to take just as long, but you could also set it to a little faster to easily allow for different durations.

下面的示例并非真的基于您的代码,而只是为了说明这个想法.它开始(在代码的按钮处)并按下一系列按钮.这些将传递到getSequence.这将返回一个命令数组,在这种情况下,仅是要打开的按钮的颜色,因此序列可以是红色,红色,红色,红色,'','','',''以使红色点亮4个间隔",然后将其关闭4个间隔".通过这种方式,您可以创建复杂的序列,并进行较小的调整,甚至可以同时点亮多个按钮.

The example below isn't really based on your code, but just to illustrate the idea. It starts (at the button of the code) with an array of buttons pressed. Those are passed to getSequence. This will return an array of commands, in this case simply the color of the button to switch on, so a sequence could be red,red,red,red,'','','','' to have red light up for 4 'intervals', and then switch it off for 4 'intervals'. This way you could create complicates sequences, and with minor adjustments you could even light up multiple buttons simultaneously.

示例中的间隔设置为1/10秒.每种颜色播放10步(= 1秒),每个暂停播放5步(= 0.5秒).在控制台中,您可以看到要播放的按钮/颜色的基本数组,然后是播放的更为复杂的序列.

The interval in the example is set to 1/10 of a second. Each color plays for 10 steps (= 1 second), and each pause plays for 5 steps (= .5 second). In the console you see the basis array of buttons/colors to play, followed by the more elaborate sequence that is played.

// The play function plays a sequence of commands
function play(sequence) {
  var index = 0;
  var lastid = '';
  var timer = setInterval(function(){
    // End the timer when at the end of the array 
    if (++index >= sequence.length) {
      clearInterval(timer);
      return;
    }
    var newid = sequence[index];
     
    if (lastid != newid) {
      // Something has changed. Check and act.
  
      if (lastid != '') {
      // The last id was set, so lets switch that off first.
        document.getElementById(lastid).classList.remove('on');
        console.log('--- ' + lastid + ' off');
      }
      
      if (newid != '') {
        // New id is set, switch it on
        document.getElementById(newid).classList.add('on');
        console.log('+++ ' + newid + ' on');
      }
      lastid = newid;
    }
  }, 100);
}

// generateSequence takes a list of buttons and converts them to a 
// sequence of color/off commands.
function generateSequence(buttons) {
  var result = [];
  for (var b = 0; b < buttons.length; b++) {
    // 'On' for 10 counts
    for (var i = 0; i < 10; i++) {
      result.push(buttons[b]);
    }
    if (b+1 < buttons.length) {
      // 'Off' for 5 counts
      for (var i = 0; i < 5; i++) {
        result.push('');
      }
    }
  }
  // One 'off' at the end
  result.push('');
  
  return result;
}

var buttons = ['red', 'green', 'red', 'yellow', 'yellow', 'blue'];
console.log(buttons);
var sequence = generateSequence(buttons);
console.log(sequence);
play(sequence);

div.button {
  width: 100px;
  height: 100px;
  opacity: .5;
  display: inline-block;
}
div.button.on {
  opacity: 1;
}
#red {
  background-color: red;
}
#green {
  background-color: green;
}
#yellow {
  background-color: yellow;
}
#blue {
  background-color: blue;
}

<div id="red" class="button"></div>
<div id="green" class="button"></div>
<div id="yellow" class="button"></div>
<div id="blue" class="button"></div>

这篇关于setInterval()添加类,然后删除类相同的时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆