为什么我的div的背景图片没有显示在ReactJS中

时间:2019-12-13 21:49:34

标签: javascript css reactjs

我试图在ReactJS的两个背景图像之间进行一些转换。在这里,我被限制在使用ReactJS元素的内联样式属性首先显示backgroundImage的阶段。

这里有一个演示:https://stackblitz.com/edit/react-evdqgw?file=index.js

这是我的ReactJS的代码段:

import React, { Component } from 'react';
import { render } from 'react-dom'; 
import './style.css';  


class App extends Component {
  constructor(props){
    super(props);
    this.imageSliderRef=React.createRef()
  }
  state = {
    currentImageIndex: 0,
    imageUrlStock:[
      "https://picsum.photos/640/480?image=1",
      "https://picsum.photos/640/480?image=2",
      "https://picsum.photos/640/480?image=3"
    ],
    currentBackgroundImage:{},
    formerBackgroundImage:{}
  };

  componentDidMount() {
    this.interval = setInterval(() => {
      this.nextSlide(); //this function change the index state. 
      }, 3000);   
    console.log("this.state: ", this.state)

  }

  nextSlide() {
    const lastIndex = this.state.imageUrlStock.length - 1;
    const { currentImageIndex } = this.state;
    const index = (currentImageIndex + 1) % (lastIndex + 1)

    // @See https://css-tricks.com/restart-css-animation/
    const elm = this.imageSliderRef
     /* .querySelector('[class^="pic"],[class*=" pix"]');
    elm.className = `pic${index+1}`
    */
    // const newone = elm.cloneNode(true);
    // elm.parentNode.replaceChild(newone, elm);

    this.setState(currentState => ({
        currentImageIndex: index,
        currentBackgroundImage:currentState.imageUrlStock[index],
        formerBackgroundImage:currentState.imageUrlStock[index-1]
    }));
  }



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

  render() {
     console.log(`
        this.state.currentBackgroundImage,
        this.state.formerBackgroundImage`,
        this.state.currentBackgroundImage,
        this.state.formerBackgroundImage
    )
    return (  
      <div ref={this.imageSliderRef} className="imageSlider"
      >
        <img className="current" style={{backgroundImage:`url(${this.state.currentBackgroundImage})`}}/> 
        <div className="former" style={{backgroundImage:`url(${this.state.formerBackgroundImage})`}}/>
      </div> 
    );
  }
}

render(<App />, document.getElementById('root'));

这是我css的代码段:

h1, p {
  font-family: Lato;
}
body {
  position: relative;
  width: 640px;
  height: 480px;
}

.imageSlider> {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 640px;
  height: 480px;
}
.current {
  z-index: 2;
  opacity: 0;
  animation: in 3s 0s;
 /* background-image:url("https://picsum.photos/640/480?image=1");*/
}
.former {
  z-index: 1;
  opacity: 1;
} 
#root .pic1.init .former {
  background-image: none;
}

/*
#root .pic1 .current,
#root .pic2 .former {
  background-image: url("https://picsum.photos/640/480?image=1");
}

#root .pic2 .current,
#root .pic3 .former {
  background-image: url("https://picsum.photos/640/480?image=2");
}
#root .pic3 .current,
#root .pic1 .former {
  background-image: url("https://picsum.photos/640/480?image=3");
}
*/

@keyframes in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

3 个答案:

答案 0 :(得分:0)

您的<img>元素(旨在显示前景图像而不是 background 图像:使用src属性代替背景样式)具有没有高度或宽度,因此没有像素可以渲染背景图像。

给出元素尺寸。

答案 1 :(得分:0)

我不确定您想做什么,但我认为您的答案可能会在这里。

请注意我的评论

编辑:@Webwoman评论后,这是新答案

const { Component } = React

class App extends Component {
  state = {
    currentImageIndex: 0,
    imageUrlStock: [
      "https://picsum.photos/640/480?image=1",
      "https://picsum.photos/640/480?image=2",
      "https://picsum.photos/640/480?image=3"
    ]
  };

  getNextImageIndex() {
    const { currentImageIndex, imageUrlStock } = this.state;
    return currentImageIndex === imageUrlStock.length - 1
      ? 0
      : currentImageIndex + 1;
  }

  componentDidMount() {
    this.interval = setInterval(() => {
      const newImageIndex = this.getNextImageIndex();
      // Define which img index should be displayed
      this.setState(currentState => ({
        currentImageIndex: newImageIndex
      }));
    }, 3000);
  }

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

  render() {
    const { imageUrlStock, currentImageIndex } = this.state;
    return (
      <div className="imageSlider">
        {imageUrlStock.map((imgURL, index) => {
          // This flag indicate if the img should show or not
          // Note that all images are loaded at first render, we only toggle the hide/show class
          // to do the transition
          const shouldShow = currentImageIndex === index;
          return (
            <div
              key={imgURL}
              className={`current ${shouldShow ? "show" : "hide"}`}
              // the image URL of a img tag should always be in src, not in the inline style
              style={{backgroundImage:`url(${imageUrlStock[index]})`}}
            />
          );
        })}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
.imageSlider > div {
  /* the "div" tag was missing after the "<" */ 
  position: absolute;
  top: 0;
  left: 0;
  width: 640px;
  height: 480px;
}

.current {
  transition: opacity 1s;
}

.current.show {
  opacity: 1;
}

.current.hide {
  opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>

供您参考:

  
  // You should either be doing this
  constructor(props){
    super(props);
    this.state = {
      name: "John"
    }
  }
  
 // Or this
 state = {
    name: "John"
 }
 
 // But not both like this. It is a bad practice
 constructor(props){
    super(props);
  }
  
 state = {
    name: "John"
 }
 

希望对您有所帮助,对每个人进行良好的编码!

答案 2 :(得分:0)

我坚韧不拔地针对所有给他们尺寸的孩子,但似乎我必须用通配符来精确说明我实际上是针对所有孩子的。尽管仅element >就足够了,但实际上您必须做element>*来针对所有孩子。

因此更新的版本起作用