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

标签 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();
#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);
}
<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>

我还需要一种方法(可能使函数递归)从 4 变回 1,我不会为此使用 jQuery。

最佳答案

这就是您要找的:

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)
}
#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);
}
<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>

为了给它一个更自然的感觉(意图、手势、活泼的印象)你需要改变 linear 到你在 CSS 中选择的缓动:

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)
}
#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);
}
<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>

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

相反,在集合上使用 setTimeout(),您最终可以选择在任何给定时刻为多个元素设置动画,并更好地(分开)控制动画细节(持续时间、计时功能)并错开一步)。

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

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

// 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)
}
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;
}
<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>


初始答案,在注意到需要 jQuery 免费解决方案之前:

// 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);
})
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);
}
<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>


尾注:这个答案甚至没有触及新的(和有前途的)动画方式:Web Animations Api ,因为它仍然是实验性技术。
WAA 使用链接进行动画处理,但提供了取消动画请求的方法。它适用于所有主流浏览器,并且可以在旧版浏览器中与 polyfill 一起使用。
一旦 Android 浏览器支持它,它可能会获得巨大的普及。在那之前,最好的动画方式是使用 CSS 动画和转换,即使不是声明式的,也支持取消请求:您只需更改属性,它会自动在同一属性上启动新动画从目前的状态,取消旧的。 CSS 当前唯一的限制是它不会根据旧的已完成多少来计算新的持续时间,这在 WAA 中是可能的。
WAA 所做的是将 CSS 动画、CSS 过渡和 SVG 动画统一在一个通用规范集下,并将提供一套统一的方法来控制动画。

关于javascript - 如何一个接一个地修改多个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42258786/

相关文章:

php - Codeigniter 通过单击按钮更改表单操作

javascript - e.touches、e.targetTouches 和 e.changedTouches 的变体

javascript - 用 JavaScript 写入或读取文件

javascript - 数据角色 ="page"打不开,为什么? (使用 PHP 和 JQuery 自动生成链接)

javascript - Angular 4 dblclick 事件在移动 View 中不起作用

c# - Bing map 路线优化

Javascript 聊天室 : How to establish who im sending a message to?

javascript - 将原始 html 快速渲染为文本

javascript - JQuery 验证错误放置重复自身

javascript - 使用 NodeJS 从 AWS S3 流式传输文件