代码之家  ›  专栏  ›  技术社区  ›  DannyArcher

我可以在设置间隔中插入多个设置超时吗?

  •  1
  • DannyArcher  · 技术社区  · 6 年前

    我刚开始学习JavaScript,现在,我正在制作一个红色、绿色和橙色的虚拟交通灯。我想通过添加一个 setInterval 到外面去。这是可能的,还是我应该用其他方法做一个循环。我试着做一个a for(;;){} 但这会导致错误,网页永远无法加载。这是我当前的代码。

    var red = document.getElementById("circleRed");
    var orange = document.getElementById('circleOrange')
    var green = document.getElementById('circleGreens');
        
    setInterval(
        
      setTimeout( function(){
        red.style.backgroundColor = "red";
      }, 2000),
        
       setTimeout(function(){
          green.style.backgroundColor = "green";
          red.style.backgroundColor = "black";
       }, 5000),
        
        setTimeout(function(){
          orange.style.backgroundColor = "orange";
          green.style.backgroundColor = "black";
        }, 10000),
        
        5000);
    #circleRed, #circleGreens, #circleOrange {
        width: 50px;
        height: 50px;
        -webkit-border-radius: 25px;
        -moz-border-radius: 25px;
        border-radius: 25px;
        margin-bottom: 10px;
        background-color: "black";
    }
    
    .back {
        width: 60px;
        margin: 10px 0px 10px 20px;
        padding-left: 10px;
        padding-top: 10px;
        padding-bottom: 10px;
        background-color: black;
    }
        
    body{
        margin: 0;
    }
    <div class="back">
      <div id="circleRed">
      </div>
      <div id="circleOrange">
      </div>
      <div id="circleGreens">
      </div>
    </div>
    5 回复  |  直到 6 年前
        1
  •  1
  •   agit    6 年前

    你可以全力以赴 setTimeout a中的函数 loop 作用调用这个循环函数 setInterval . 注意:我还更改了代码中的一些颜色更改部分。

    JSIDLE链接: https://jsfiddle.net/zgdx5xan/

    var red = document.getElementById("circleRed");
    var orange = document.getElementById('circleOrange')
    var green = document.getElementById('circleGreens');
    
    loop();
    setInterval(loop,11000);
    
    function loop(){
    	console.log("loop started")
      setTimeout( function(){
        red.style.backgroundColor = "red";
        orange.style.backgroundColor = "black";
        green.style.backgroundColor = "black";
        console.log("red opened")
      }, 2000);
    
       setTimeout(function(){
        green.style.backgroundColor = "green";
        red.style.backgroundColor = "black";
        console.log("green opened")
      }, 5000);
    
      setTimeout(function(){
        orange.style.backgroundColor = "orange";
        green.style.backgroundColor = "black";
        red.style.backgroundColor = "black";
        console.log("orange opened")    
      }, 10000);
    }
    #circleRed, #circleGreens, #circleOrange {
      width: 50px;
      height: 50px;
      -webkit-border-radius: 25px;
      -moz-border-radius: 25px;
      border-radius: 25px;
      margin-bottom: 10px;
      background-color: "black";
    }
    
    
    
    .back{
      width: 60px;
      margin: 10px 0px 10px 20px;
      padding-left: 10px;
      padding-top: 10px;
      padding-bottom: 10px;
      background-color: black;
    }
    
    body{
      margin: 0;
    }
     
       <div class="back">
        <div id="circleRed">
    
        </div>
        <div id="circleOrange">
    
        </div>
        <div id="circleGreens">
    
        </div>
      </div>
     
        2
  •  1
  •   leepowell    6 年前

    与setTimeout一样,setInterval也需要将函数作为第一个参数传递,在该函数中,您可以编写setTimeout。

    var red = document.getElementById("circleRed");
    var orange = document.getElementById('circleOrange');
    var green = document.getElementById('circleGreens');
    
    setInterval(function () {
      red.style.backgroundColor = "black";
      orange.style.backgroundColor = "black";
      green.style.backgroundColor = "black";
    
      setTimeout(function () {
        red.style.backgroundColor = "red";
      }, 2000);
    
      setTimeout(function () {
        green.style.backgroundColor = "green";
        red.style.backgroundColor = "black";
      }, 5000);
    
      setTimeout(function () {
        orange.style.backgroundColor = "orange";
        green.style.backgroundColor = "black";
      }, 8000);
    }, 10000)
    

    我稍微调整了一下你的计时,因为你的最后超时时间比间隔时间长。你可以在这里看到这一点: codepen example

        3
  •  1
  •   Vanojx1    6 年前

    把红绿灯想象成一个有3个状态的物体,雷登、格林和橘子。您需要循环状态,因此从重做开始,传递序列中的下一个状态,并在最后一个状态中重置。我认为这里不需要setInterval,因为它会让您关心与此无关的总时间。

    var red = document.getElementById("circleRed");
    var orange = document.getElementById('circleOrange')
    var green = document.getElementById('circleGreens');
    
    var redFor = 200 //2000
    var greenFor = 500 //5000
    var orangeFor = 1000 //10000
    
    let redOn = function(next) {
      red.style.backgroundColor = "red";
      orange.style.backgroundColor = "black";
      setTimeout(next, redFor);
    }
    
    let orangeOn = function(next) {
      orange.style.backgroundColor = "orange";
      green.style.backgroundColor = "black";
      setTimeout(next, orangeFor);
    }
    
    let greenOn = function(next) {
      green.style.backgroundColor = "green";
      red.style.backgroundColor = "black";
      setTimeout(next, greenFor);
    }
    
    let start = function() {
      redOn(function() {
        greenOn(function() {
          orangeOn(start)
        })
      })
    }
    
    start()
    #circleRed,
    #circleGreens,
    #circleOrange {
      width: 50px;
      height: 50px;
      -webkit-border-radius: 25px;
      -moz-border-radius: 25px;
      border-radius: 25px;
      margin-bottom: 10px;
      background-color: "black";
    }
    
    .back {
      width: 60px;
      margin: 10px 0px 10px 20px;
      padding-left: 10px;
      padding-top: 10px;
      padding-bottom: 10px;
      background-color: black;
    }
    
    body {
      margin: 0;
    }
    <html>
    
    <head>
      <link rel="stylesheet" type="text/css" href="object2.css">
      <meta charset="utf-8">
      <title></title>
    </head>
    
    <body>
      <div class="back">
        <div id="circleRed"></div>
        <div id="circleOrange"></div>
        <div id="circleGreens"></div>
      </div>
      <script src="objects1.js"></script>
    </body>
    
    </html>
        4
  •  1
  •   Jordi Nebot Roberto Zvjerković    6 年前

    var red    = document.getElementById('circleRed');
    var orange = document.getElementById('circleOrange');
    var green  = document.getElementById('circleGreens');
    
    /* Set an array with the desired order to turn on lights */
    var lights = [red, green, orange];
    
    function open(light) {
        light.classList.add('opened');
    }
    
    function close(light) {
        light.classList.remove('opened');
    }
    
    
    function change() {
        close(lights[i]);
        i = (i + 1) % lights.length;
        open(lights[i]);
    }
    
    /* Start */
    var i = 0;
    open(lights[i]);
    setInterval(change, 1000);
    .circle {
        width: 50px;
        height: 50px;
        border-radius: 25px;
        margin: 5px;
        opacity: 0.2;
        transition: opacity 200ms;
    }
    
    .circle.opened {
        opacity: 1;
    }
    
    #circleRed {
        background-color: red;
    }
    
    #circleOrange {
        background-color: orange;
    }
    
    #circleGreens {
        background-color: green;
    }
    
    
    .back {
        width: 60px;
        padding: 5px;
        background-color: black;
    }
    <div class="back">
      <div id="circleRed" class="circle"></div>
      <div id="circleOrange" class="circle"></div>
      <div id="circleGreens" class="circle"></div>
    </div>

    说明:

    在我的示例中,不是将每个圆的背景色从黑色更改为自己的颜色以点亮该圆,而是将其关闭,而是将所有圆的各自颜色(红色、绿色或橙色)褪色为(几乎)透明 opacity: 0.2 (最初我使用0,但我认为使用0.2看起来更好)请参见: opacity .

    所以,所有元素都带有类 .circle 拥有:

    .circle {
        /* Other properties */
        opacity: 0.2;
    }
    

    然后,我使用一个名为 opened 将不透明度设置为1,使圆可见。

    .circle.opened {
        opacity: 1;
    }
    

    自从 .circle.opened 具有更高的 specificity 不仅仅是 .圆圈 ,不透明度:1适用于具有两个类的元素( circle 开的 ).

    开的 从一个轻量级项目中,我使用了两个简单的函数 open close 操纵元素的 classList . 这很重要 . 一般来说,更建议在类中定义元素的属性(样式),并使用JS添加或删除此类来更改元素,从而直接使用JS修改元素的样式。

    因此,它更干净,更推荐:

    /* CSS */
    .red { background-color: red }
    
    /* Javascript */
    var element = document.getElementById('#element_ID');
    element.classList.add('red');
    

    比:

    /* Javascript */
    var element = document.getElementById('#element_ID');
    element.style.backgroundColor = 'red';
    

    尽管第二种方式似乎更容易。

    var lights = [red, green, orange];
    

    正如你所见,灯光的每个元素 Array 是其中一个圆,我们已经用 document.getElementById() (如果您不熟悉数组,请花一些时间阅读和理解它们是什么以及它们是如何工作的。它们是任何编程语言中最基本的数据结构之一,因此掌握它们很重要。)

    首先,我启动一个全局变量来 0 ( var i = 0 )我用以下方法点亮第一盏灯:

    open(lights[i]);
    

    自从 i 等于0, lights[i] 所以 lights[0] red (在JS中,与大多数语言一样,数组从0开始计算元素)。这边 open(lights[i]) 与相同 open(red) .

    然后我做一个 setInterval(change, 1000) 所以每秒钟函数 change() 被称为。这是什么 change 功能是什么?

    基本上:

    // Turn off the current light
    close(lights[i]);
    
    // Increment i, so that lights[i] points to the next element... 
    i = (i + 1) % lights.length;
    
    // Turn on this next element
    open(lights[i]);
    

    这里最罕见的可能是增量。我为什么这么做 i = (i + 1) % lights.length 而不仅仅是 i++ .

    如果我这样做 连续呼叫后 改变 , 一、 将是:0、1、2、3、4、5、6。。。所以,当我尝试访问 我会得到一个错误,因为在位置3,4,5中没有元素。。。的 lights 大堆

    我需要我的序列是:0,1,2,0,1,2,0,1,2。。。

    我如何得到这个所需的序列而不是0,1,2,3,4,5,6?

    也许更容易理解的方法是:

    i++;
    if (i > 2) {
        i = 0;
    }
    

    但我用的是 Remainder 操作员( % )达到同样的效果。

    我希望这有帮助!


    var lights = {
        red: {
            node: document.getElementById('circleRed'),
            duration: 4000,
        },
        green: {
            node: document.getElementById('circleGreens'),
            duration: 2000,
        },
        orange: {
            node: document.getElementById('circleOrange'),
            duration: 800,
        }
    };
    
    var order = ['red', 'green', 'orange'];
    
    
    function open(light) {
        light.node.classList.add('opened');
    }
    
    function close(light) {
        light.node.classList.remove('opened');
    }
    
    function change() {
        close(lights[order[i]]);
        i = (i + 1) % order.length;
        open(lights[order[i]]);
        setTimeout(change, lights[order[i]].duration);
    }
    
    /* Start */
    var i = 0;
    open(lights[order[i]]);
    
    setTimeout(change, lights[order[i]].duration);
    .circle {
        width: 50px;
        height: 50px;
        border-radius: 25px;
        margin: 5px;
        opacity: 0;
        transition: opacity 200ms;
    }
    
    .circle.opened {
        opacity: 1;
    }
    
    #circleRed {
        background-color: red;
    }
    
    #circleOrange {
        background-color: orange;
    }
    
    #circleGreens {
        background-color: green;
    }
    
    
    .back {
        width: 60px;
        padding: 5px;
        background-color: black;
    }
    <div class=“back”>
    <div id=“circleRed”class=“circle”></div>
    <div id=“circleOrange”class=“circle”></div>
    <div id=“circleGreens”class=“circle”></div>
    </div>
        5
  •  0
  •   MHD Alaa Alhaj Shuo    6 年前

    全部放置 setTimeout( function(){})

    注:制作 setInterval 如果工作正常,毫秒数必须至少等于 setTimeout 功能。

    你还忘了设置 orange red 正在出现。

    var red = document.getElementById("circleRed");
    var orange = document.getElementById('circleOrange')
    var green = document.getElementById('circleGreens');
        
    setInterval(function(){ myTimer() }, 17000);
        function myTimer() {
      setTimeout( function(){
        red.style.backgroundColor = "red";
        orange.style.backgroundColor = "black";
      }, 2000),
        
       setTimeout(function(){
          green.style.backgroundColor = "green";
          red.style.backgroundColor = "black";
       }, 5000),
        
        setTimeout(function(){
          orange.style.backgroundColor = "orange";
          green.style.backgroundColor = "black";
        }, 10000)
        }
        myTimer();
    #circleRed, #circleGreens, #circleOrange {
        width: 50px;
        height: 50px;
        -webkit-border-radius: 25px;
        -moz-border-radius: 25px;
        border-radius: 25px;
        margin-bottom: 10px;
        background-color: "black";
    }
    
    .back {
        width: 60px;
        margin: 10px 0px 10px 20px;
        padding-left: 10px;
        padding-top: 10px;
        padding-bottom: 10px;
        background-color: black;
    }
        
    body{
        margin: 0;
    }
    <div class="back">
      <div id="circleRed">
      </div>
      <div id="circleOrange">
      </div>
      <div id="circleGreens">
      </div>
    </div>