为什么嵌套的SetTimeouts无法与Internet Explorer 11一起使用?

时间:2019-09-26 22:11:11

标签: javascript reactjs internet-explorer-11 settimeout setinterval

我目前有类似如下的代码:

import React from 'react';
import testimonials from './testimonials';
import {INTERVAL, FADE_OUT_ANIMATION_TIME, FADE_IN_ANIMATION_TIME} from './config';

class Carousel extends React.PureComponent {
  constructor(props) {
    super(props);
    this.startCarousel = this.startCarousel.bind(this);
    this.currentIdx = 0;
  }

  startCarousel = () => {
    this.intervalID = setInterval(() => {
      const {currentIdx, carouselContainer} = this;
      const testimonials = carouselContainer.children;
      const nextIdx = currentIdx + 1 !== testimonials.length ? currentIdx + 1 : 0;

      testimonials[currentIdx].classList.add('fadeOut');
      setTimeout(() => {
        testimonials[currentIdx].classList.add('hide');
        testimonials[currentIdx].classList.remove('fadeOut');

        testimonials[nextIdx].classList.remove('hide');
        testimonials[nextIdx].classList.add('fadeIn');
        setTimeout(() => testimonials[nextIdx].classList.remove('fadeIn'), FADE_IN_ANIMATION_TIME);
      }, FADE_OUT_ANIMATION_TIME);

      this.currentIdx = nextIdx;
    }, INTERVAL);
  }

  componentDidMount() {
    this.startCarousel();
  }

  componentWillUnmount() {
    clearInterval(this.intervalID);
  }

  render() {
    return (
      <div className="Carousel__container" ref={(ele) => this.carouselContainer = ele} >
        {testimonials.map(renderTestimonials)}
      </div>
    );
  }
}

export default Carousel;

我要做的就是循环遍历轮播容器中呈现的不同元素,更改每个间隔周围的类名以触发动画和隐藏/显示元素。间隔和超时时间供参考:

export const INTERVAL = 8500;
export const FADE_OUT_ANIMATION_TIME = 800;
export const FADE_IN_ANIMATION_TIME = 1200;

这适用于Chrome,Safari,Firefox,Edge,但不适用于Internet Explorer11。轮播永远不会循环到第一个元素。据我所知,这似乎不是CSS问题,因为当我在开发人员控制台中手动添加相关的类名时,动画会正确触发和设置动画。 [DOMElement].classList.add/remove方法似乎也可以正常工作。我尝试在IE11控制台中手动重新创建上述setInterval代码,而setTimeout中嵌套的setInterval似乎有问题吗?

根据我的观察,似乎fadeIn类名已正确添加,但hide类名并未删除,除非它循环回到容器中的第一个元素。

任何人都对这里可能发生的事情有任何想法吗?关于如何使这项工作达到预期的任何建议?

1 个答案:

答案 0 :(得分:0)

我认为该问题与currentIdx值设置有关,请参考以下代码,它对我而言效果很好:

export const INTERVAL = 8500;
export const FADE_OUT_ANIMATION_TIME = 800;
export const FADE_IN_ANIMATION_TIME = 1200;
var currentIdx =0;

  class Carousel extends React.PureComponent {
    constructor(props) {
      super(props); 
    }

    startCarousel = () => {
      this.intervalID = setInterval(() => { 
        const testimonials = document.getElementsByClassName("imagecontent");
        const nextIdx = currentIdx + 1 !== testimonials.length ? currentIdx + 1 : 0;

        testimonials[currentIdx].classList.add('fadeOut');
        setTimeout(function () {
          testimonials[currentIdx].classList.add('hide');
          testimonials[currentIdx].classList.add('fadeOut');

          testimonials[nextIdx].classList.remove('hide');
          testimonials[nextIdx].classList.add('fadeIn');
          setTimeout(function () {
              console.log("nested settimeout");
              return testimonials[nextIdx].classList.remove('fadeIn');
          }, FADE_IN_ANIMATION_TIME);
          currentIdx =  currentIdx + 1 !== testimonials.length ? currentIdx + 1 : 0;
      }, FADE_OUT_ANIMATION_TIME);
      }, INTERVAL);
    }

    render() {
      return (
        <div >
            <input type="button" value="Start Carousel" onClick={ this.startCarousel} />
            <br />
          <div className="imagecontent image1">
          </div>
          <div className="imagecontent hide image2">
          </div>
          <div className="imagecontent hide image3">
          </div>
        </div>
      );
    }
  }

结果如下:

enter image description here