如何一个接一个地修改多个元素

时间:2017-02-15 19:52:25

标签: javascript

我正在使用图像推子。我有它,以便它淡化getElementById方法选择的图像(或在这种情况下div与背景颜色),但我想知道如何修改JavaScript代码以选择所有div元素和一个接一个地淡出。



var c = document.getElementById("one");

function fade(){
  if (!c.style.opacity){
    c.style.opacity = 1;
  };
  
  var interval = setInterval (fadeout, 200);
  
  function fadeout(){
    c.style.opacity -= .05;
    
    if (c.style.opacity <= 0){
      clearInterval(interval);
    };
  };
};

fade();
&#13;
#container{
  position: relative;
  margin: 0 auto;
  text-align: center;
  width: 350px;
  height: 350px;
  background-color: rgb(200,200,200);
}

.inner{
  position: absolute;
  margin: 0 auto;
  left: 25px;
  top: 25px;
  width: 300px;
  height: 300px;
}

#one{
  background-color: rgb(100,100,100);
}

#two{
  background-color: rgb(0,160,230);
}

#three {
  background-color: rgb(0,255,130);
}

#four{
  background-color: rgb(255,130,255);
}
&#13;
<div id="container">
  <div class="inner" id="one"></div>
  <div class="inner" id="two"></div>
  <div class="inner" id="three"></div>
  <div class="inner" id="four"></div>
</div>
&#13;
&#13;
&#13;

我还需要一种方法(可能使函数递归)从四个回到一个,我不会使用jQuery。

1 个答案:

答案 0 :(得分:5)

这就是你要找的东西:

&#13;
&#13;
var interval = 4000,
  collection = document.querySelectorAll('#container>.inner');

for (var i = 0; i < collection.length; i++) {
  (function(i) {
    setTimeout(function() {
      collection[collection.length - i - 1].style.opacity = 0;
    }, i * interval);
  })(i)
}
&#13;
#container {
  position: relative;
  margin: 0 auto;
  text-align: center;
  width: 350px;
  height: 350px;
  background-color: rgb(200, 200, 200);
}

.inner {
  position: absolute;
  margin: 0 auto;
  left: 25px;
  top: 25px;
  width: 300px;
  height: 300px;
  transition: opacity 4s linear;
}

#one {
  background-color: rgb(100, 100, 100);
}

#two {
  background-color: rgb(0, 160, 230);
}

#three {
  background-color: rgb(0, 255, 130);
}

#four {
  background-color: rgb(255, 130, 255);
}
&#13;
<div id="container">
  <div class="inner" id="one"></div>
  <div class="inner" id="two"></div>
  <div class="inner" id="three"></div>
  <div class="inner" id="four"></div>
</div>
&#13;
&#13;
&#13;

为了给它更多自然的感觉(意图,手势,生动的印象),您需要将linear更改为您在CSS中选择的宽松:

&#13;
&#13;
var interval = 4000,
  collection = document.querySelectorAll('#container>.inner');

for (var i = 0; i < collection.length; i++) {
  (function(i) {
    setTimeout(function() {
      collection[collection.length - i - 1].style.opacity = 0;
    }, i * interval);
  })(i)
}
&#13;
#container {
  position: relative;
  margin: 0 auto;
  text-align: center;
  width: 350px;
  height: 350px;
  background-color: rgb(200, 200, 200);
}

.inner {
  position: absolute;
  margin: 0 auto;
  left: 25px;
  top: 25px;
  width: 300px;
  height: 300px;
  transition: opacity 4s cubic-bezier(.6, 0, .3, 1);
}

#one {
  background-color: rgb(100, 100, 100);
}

#two {
  background-color: rgb(0, 160, 230);
}

#three {
  background-color: rgb(0, 255, 130);
}

#four {
  background-color: rgb(255, 130, 255);
}
&#13;
<div id="container">
  <div class="inner" id="one"></div>
  <div class="inner" id="two"></div>
  <div class="inner" id="three"></div>
  <div class="inner" id="four"></div>
</div>
&#13;
&#13;
&#13;

原则:每当你想要错开动画时(在元素集合上重复完全相同的动画),在前一个结尾处链接一个动画的开头,至少可以说是不合适的。你限制自己总是不得不等待一个动画结束才能开始下一个动画。但是,在执行脚本时,如果操作的持续时间未知,则通常需要此行为。在这里,它的持续时间相同,因此链接只是一个无用的限制。

相反,在集合上使用setTimeout(),您最终可以选择在任何给定时刻设置多个元素的动画,并对动画细节(持续时间,计时功能和交错步骤)进行更好(分离)的控制。

您的方法的另一个大问题是,您为每个元素进行了20次更改,而不是仅针对一个元素。 CSS动画可让您控制animation-durationanimation-timing-function(动画动画时非常重要)和animation-delay(此处未使用)。此外,它在浏览器上更流畅,更轻松。

我将通过动画而不是不透明度来举例说明:

&#13;
&#13;
// only set the stagger step and the collection in js
// set animation duration and easing in CSS for best results

var interval = 63, // stagger step
  collection = document.querySelectorAll('div');
// in your case, use document.querySelectorAll('#container>.inner');

for (var i = 0; i < collection.length; i++) {
  (function(i) {
    setTimeout(function() {
      collection[i].style.transform = 'translateX(0)';
    }, i * interval);
  })(i)
}
&#13;
div {
  background-color: #ddd;
  margin-top: 1px;
  min-height: .5rem;
  transform: translateX(100%);
  /* here it is: duration 300ms, and transition
   * I've put in cubic, as it's good for staggered movement
   * it looks natural. For opacity it doesn't matter
   * it can be linear, ease-out, anything.
   */
  transition: transform 1s cubic-bezier(.5, 0, .1, 1);
}

body {
  overflow-x: hidden;
  margin: 0;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
&#13;
&#13;
&#13;

最初的答案,在注意到jQuery免费解决方案之前是必需的:

&#13;
&#13;
// only set the stagger step and the collection in js
// set animation duration and easing in CSS for best results

var interval = 42, // stagger step
  collection = $('div'); // in your case, use $('#container>.inner');

collection.each(function(i) {
  setTimeout(function() {
    collection.eq(i).css('opacity', 0);
  }, i * interval);
})
&#13;
div {
  background-color: #ddd;
  margin-top: 1px;
  min-height: .5rem;
  /* here it is: duration 300ms, and transition
   * I've put in cubic, as it's good for staggered movement
   * it looks natural. For opacity it doesn't matter
   * it can be linear, ease-out, anything.
   */
  transition: opacity 300ms cubic-bezier(.4, 0, .2, 1);
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>    <div></div>    <div></div>
<div></div>
&#13;
&#13;
&#13;

结束说明:这个答案甚至没有触及新的(有希望的)动画制作方式:Web Animations Api,因为它仍然是实验技术。
WAA使用链接动画,但提供取消动画请求的方法。它适用于所有主流浏览器,可以在旧浏览器中与 polyfill 一起使用 一旦Android浏览器支持它,它可能会获得巨大的普及。在此之前,动画的最佳方式是使用CSS动画和过渡,即使不是声明性的,它也支持取消请求:您只需更改属性并自动从当前属性开始同一属性上的新动画取消旧的。唯一的CSS当前限制是它不会根据旧的持续时间计算新的持续时间,这在WAA中是可能的。
WAA所做的是在一组通用规范下统一CSS动画,CSS过渡和SVG动画,并提供一套统一的方法来控制动画。