如何在javascript中设置循环

时间:2017-02-10 04:12:14

标签: javascript jquery css-transitions

我想在此代码中设置循环。我怎么能这样做?

这是一个插件,我想让这个插件不断显示效果。为此,我必须使用某种循环。但我不知道该怎么做。

var steps = $(".step");
console.dir(steps);

setTimeout(function() {
    steps.each(function(index) {
        var _t = $(this);
        setTimeout(function() {
            _t.addClass('done');
        }, 1250 * index * 1.5);
    });
}, 500);
body {
    font-family: 'Roboto Condensed';
    height: 700px;
    width: 100vw;
    padding: 0;
    background-image: -webkit-radial-gradient(#051b23, #04141a);
    background-image: radial-gradient(#051b23, #04141a);
}
h1 {
    color: #fcb034;
    text-align: center;
    font-size: 7vw;
    margin-top: 10vh;
    letter-spacing: 3px;
    position: absolute;
    width: 100%;
}
.icon {
    display: inline-block;
    width: 1.5em;
    height: 1.5em;
    fill: none;
}
.hidden {
    display: none;
}
.progress {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    width: 100%;
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
    margin: 80% 0 0 10%;
}
.step {
    -webkit-box-flex: 1;
    -ms-flex-positive: 1;
    flex-grow: 1;
    position: relative;
}
.step-progress {
    width: 100%;
    height: 0.25em;
    background: #fcb034;
}
.icon-wrapper {
    text-align: center;
    display: inline-block;
}
.step.done .step-progress:after {
    position: absolute;
    content: '';
    height: 0.25em;
    width: 0;
    background-color: #0087B3;
    -webkit-animation: growLine 1s linear forwards;
    animation: growLine 1s linear forwards;
}
.icon-checkmark {
    position: absolute;
    top: -0.55em;
    left: -0.125em;
    border: 0.125em solid #fcb034;
    background: #051B23;
    width: 1em;
    height: 1em;
    border-radius: 50%;
    padding: 0.125em;
    border-radius: 50%;
    -webkit-transition: all 0.25s linear;
    transition: all 0.25s linear;
}
.step.done .icon-checkmark {
    background: #0087B3;
    border-color: #0087B3;
}
.icon-checkmark .path1 {
    stroke: #aaa;
    stroke-width: 4;
    stroke-linecap: square;
    stroke-dasharray: 1000;
    stroke-dashoffset: 1000;
    fill: empty;
}
.step.done .icon-checkmark .path1 {
    -webkit-animation: dash 5s linear forwards;
    animation: dash 5s linear forwards;
    stroke: #fcb034;
}
.step-text {
    position: relative;
    margin-left: -50%;
    letter-spacing: 1px;
    font-weight: bold;
    color: #aaa;
    margin-top: 0;
    opacity: 0;
}
.step.done .step-text {
    color: #0087B3;
    -webkit-animation: dropText 0.5s linear forwards;
    animation: dropText 0.5s linear forwards;
}
@-webkit-keyframes dash {
    to {
        stroke-dashoffset: 0;
    }
}
@keyframes dash {
    to {
        stroke-dashoffset: 0;
    }
}
@-webkit-keyframes growLine {
    to {
        width: 100%;
    }
}
@keyframes growLine {
    to {
        width: 100%;
    }
}
@-webkit-keyframes dropText {
    to {
        padding-top: 1em;
        opacity: 1;
    }
}
@keyframes dropText {
    to {
        padding-top: 1em;
        opacity: 1;
    }
}
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Step Progress Bar</title>

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">

    <link rel='stylesheet prefetch' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css'>

    <link rel="stylesheet" href="css/style.css">


</head>

<body>
    <h1>PROGRESS BAR</h1>

    <div class="progress">
        <div class="step">
            <div class="step-progress"></div>
            <div class="icon-wrapper">
                <svg class="icon icon-checkmark" viewBox="0 0 32 32">
                    <path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>
                </svg>
                <div class="step-text">ENROLLED</div>
            </div>
        </div>
        <div class="step">
            <div class="step-progress"></div>
            <div class="icon-wrapper">
                <svg class="icon icon-checkmark" viewBox="0 0 32 32">
                    <path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>
                </svg>
                <div class="step-text">APPLIED</div>
            </div>
        </div>
        <div class="step">
            <div class="step-progress"></div>
            <div class="icon-wrapper">
                <svg class="icon icon-checkmark" viewBox="0 0 32 32">
                    <path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>
                </svg>
                <div class="step-text">CONFIRMED</div>
            </div>
        </div>
        <div class="step">
            <div class="icon-wrapper">
                <svg class="icon icon-checkmark" viewBox="0 0 32 32">
                    <path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>
                </svg>
                <div class="step-text">DONE!</div>
            </div>
        </div>
    </div>
    <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js'></script>

    <script src="js/index.js"></script>

</body>

</html>

2 个答案:

答案 0 :(得分:1)

以下对JavaScript的编辑允许动画无限循环。

总结:

  • 我已将您的JavaScript分解为两个单独的函数 - animatereset
  • animate内,我们会检查我们何时在最终的step元素上进行迭代,并在发生这种情况时调用reset函数
  • reset内,我们从每个元素中删除done类,然后再次调用animate函数

&#13;
&#13;
var steps = $(".step");
// Find out the number of '.step' items in DOM and
// decrement count by 1 so that we can count from 0.
var stepsCount = steps.length - 1;
//console.dir(steps);

function animate () {
  setTimeout(function() {
    steps.each(function(index) {
      var _t = $(this);
      setTimeout(function() {
        _t.addClass('done');

        if (index === stepsCount) {
          setTimeout(function() {
            // If we've reached the final item call the reset function after a 2 sec delay,
            // so that the user can see the animation in its end state before we restart.
            reset();
          }, 2000);
        }
      }, 1250*index*1.5);
    });
  }, 500);
}

function reset () {
  // Iterate over DOM and remove `.done`
  steps.each(function(index) {
    var _t = $(this);
    _t.removeClass('done');
  });
  
  // Start the animation again
  animate();
}

animate(); // Initial call to animate
&#13;
body {
  font-family: 'Roboto Condensed';
  height:700px;
  width: 100vw;
  padding: 0;
  background-image: -webkit-radial-gradient(#051b23, #04141a);
  background-image: radial-gradient(#051b23, #04141a);
}

h1 {
  color: #fcb034;
  text-align: center;
  font-size: 7vw;
  margin-top: 10vh;
  letter-spacing: 3px;
  position: absolute;
  width: 100%;
}

.icon {
  display: inline-block;
  width: 1.5em;
  height: 1.5em;
  fill: none;
}

.hidden {
  display: none;
}

.progress {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  width: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
          transform: translate(-50%, -50%);
  margin: 80% 0 0 10%;
}

.step {
  -webkit-box-flex: 1;
      -ms-flex-positive: 1;
          flex-grow: 1;
  position: relative;
}

.step-progress {
  width: 100%;
  height: 0.25em;
  background: #fcb034;
}

.icon-wrapper {
  text-align: center;
  display: inline-block;
}

.step.done .step-progress:after {
  position: absolute;
  content: '';
  height: 0.25em;
  width: 0;
  background-color: #0087B3;
  -webkit-animation: growLine 1s linear forwards;
          animation: growLine 1s linear forwards;
}

.icon-checkmark {
  position: absolute;
  top: -0.55em;
  left: -0.125em;
  border: 0.125em solid #fcb034;
  background: #051B23;
  width: 1em;
  height: 1em;
  border-radius: 50%;
  padding: 0.125em;
  border-radius: 50%;
  -webkit-transition: all 0.25s linear;
  transition: all 0.25s linear;
}

.step.done .icon-checkmark {
  background: #0087B3;
  border-color: #0087B3;
}

.icon-checkmark .path1 {
  stroke: #aaa;
  stroke-width: 4;
  stroke-linecap: square;
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  fill: empty;
}

.step.done .icon-checkmark .path1 {
  -webkit-animation: dash 5s linear forwards;
          animation: dash 5s linear forwards;
  stroke: #fcb034;
}

.step-text {
  position: relative;
  margin-left: -50%;
  letter-spacing: 1px;
  font-weight: bold;
  color: #aaa;
  margin-top: 0;
  opacity: 0;
}

.step.done .step-text {
  color: #0087B3;
  -webkit-animation: dropText 0.5s linear forwards;
          animation: dropText 0.5s linear forwards;
}

@-webkit-keyframes dash {
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes dash {
  to {
    stroke-dashoffset: 0;
  }
}
@-webkit-keyframes growLine {
  to {
    width: 100%;
  }
}
@keyframes growLine {
  to {
    width: 100%;
  }
}
@-webkit-keyframes dropText {
  to {
    padding-top: 1em;
    opacity: 1;
  }
}
@keyframes dropText {
  to {
    padding-top: 1em;
    opacity: 1;
  }
}
&#13;
<!DOCTYPE html>
<html >
<head>
  <meta charset="UTF-8">
  <title>Step Progress Bar</title>
  
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">

  <link rel='stylesheet prefetch' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>
  <h1>PROGRESS BAR</h1>

<div class="progress">
  <div class="step">
    <div class="step-progress"></div>
    <div class="icon-wrapper">
      <svg class="icon icon-checkmark" viewBox="0 0 32 32"><path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>  </svg>
      <div class="step-text">ENROLLED</div>
    </div>
  </div>
  <div class="step">
    <div class="step-progress"></div>
    <div class="icon-wrapper">
      <svg class="icon icon-checkmark" viewBox="0 0 32 32"><path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>  </svg>
      <div class="step-text">APPLIED</div>
    </div>
  </div>
  <div class="step">
    <div class="step-progress"></div>
    <div class="icon-wrapper">
      <svg class="icon icon-checkmark" viewBox="0 0 32 32"><path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>  </svg>
      <div class="step-text">CONFIRMED</div>
    </div>
  </div>
  <div class="step">
    <div class="icon-wrapper">
      <svg class="icon icon-checkmark" viewBox="0 0 32 32"><path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>  </svg>
      <div class="step-text">DONE!</div>      
    </div>
  </div>
</div>
  <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js'></script>

    <script src="js/index.js"></script>

</body>
</html>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您可以使用递归函数,以便在每次超时后调用自己进行下一步。

注意:要使代码片段起作用,我必须将progress CSS中的左边距更改为10而不是原来的80:

// an immediately invoked function:
(function progress(steps) {
    setTimeout(function() {
        if (!steps.length) {
            // start again:
            steps = $(".step").removeClass('done');
        } else {
            // animate the current step, and remove it from the list
            steps.eq(0).addClass('done');
            steps = steps.slice(1);
        }
        progress(steps); // recursive call for the remaining steps
    }, 1250);
})($(".step")); // pass it all the step elements
body {
    font-family: 'Roboto Condensed';
    height: 700px;
    width: 100vw;
    padding: 0;
    background-image: -webkit-radial-gradient(#051b23, #04141a);
    background-image: radial-gradient(#051b23, #04141a);
}
h1 {
    color: #fcb034;
    text-align: center;
    font-size: 7vw;
    margin-top: 10vh;
    letter-spacing: 3px;
    position: absolute;
    width: 100%;
}
.icon {
    display: inline-block;
    width: 1.5em;
    height: 1.5em;
    fill: none;
}
.hidden {
    display: none;
}
.progress {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    width: 100%;
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
    margin: 10% 0 0 10%;
}
.step {
    -webkit-box-flex: 1;
    -ms-flex-positive: 1;
    flex-grow: 1;
    position: relative;
}
.step-progress {
    width: 100%;
    height: 0.25em;
    background: #fcb034;
}
.icon-wrapper {
    text-align: center;
    display: inline-block;
}
.step.done .step-progress:after {
    position: absolute;
    content: '';
    height: 0.25em;
    width: 0;
    background-color: #0087B3;
    -webkit-animation: growLine 1s linear forwards;
    animation: growLine 1s linear forwards;
}
.icon-checkmark {
    position: absolute;
    top: -0.55em;
    left: -0.125em;
    border: 0.125em solid #fcb034;
    background: #051B23;
    width: 1em;
    height: 1em;
    border-radius: 50%;
    padding: 0.125em;
    border-radius: 50%;
    -webkit-transition: all 0.25s linear;
    transition: all 0.25s linear;
}
.step.done .icon-checkmark {
    background: #0087B3;
    border-color: #0087B3;
}
.icon-checkmark .path1 {
    stroke: #aaa;
    stroke-width: 4;
    stroke-linecap: square;
    stroke-dasharray: 1000;
    stroke-dashoffset: 1000;
    fill: empty;
}
.step.done .icon-checkmark .path1 {
    -webkit-animation: dash 5s linear forwards;
    animation: dash 5s linear forwards;
    stroke: #fcb034;
}
.step-text {
    position: relative;
    margin-left: -50%;
    letter-spacing: 1px;
    font-weight: bold;
    color: #aaa;
    margin-top: 0;
    opacity: 0;
}
.step.done .step-text {
    color: #0087B3;
    -webkit-animation: dropText 0.5s linear forwards;
    animation: dropText 0.5s linear forwards;
}
@-webkit-keyframes dash {
    to {
        stroke-dashoffset: 0;
    }
}
@keyframes dash {
    to {
        stroke-dashoffset: 0;
    }
}
@-webkit-keyframes growLine {
    to {
        width: 100%;
    }
}
@keyframes growLine {
    to {
        width: 100%;
    }
}
@-webkit-keyframes dropText {
    to {
        padding-top: 1em;
        opacity: 1;
    }
}
@keyframes dropText {
    to {
        padding-top: 1em;
        opacity: 1;
    }
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel='stylesheet prefetch' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css'>
<link rel="stylesheet" href="css/style.css">
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js'></script>
<h1>PROGRESS BAR</h1>
<div class="progress">
    <div class="step">
        <div class="step-progress"></div>
        <div class="icon-wrapper">
            <svg class="icon icon-checkmark" viewBox="0 0 32 32">
                <path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>
            </svg>
            <div class="step-text">ENROLLED</div>
        </div>
    </div>
    <div class="step">
        <div class="step-progress"></div>
        <div class="icon-wrapper">
            <svg class="icon icon-checkmark" viewBox="0 0 32 32">
                <path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>
            </svg>
            <div class="step-text">APPLIED</div>
        </div>
    </div>
    <div class="step">
        <div class="step-progress"></div>
        <div class="icon-wrapper">
            <svg class="icon icon-checkmark" viewBox="0 0 32 32">
                <path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>
            </svg>
            <div class="step-text">CONFIRMED</div>
        </div>
    </div>
    <div class="step">
        <div class="icon-wrapper">
            <svg class="icon icon-checkmark" viewBox="0 0 32 32">
                <path class="path1" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path>
            </svg>
            <div class="step-text">DONE!</div>
        </div>
    </div>
</div>