我试图在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;
}
}
答案 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>*
来针对所有孩子。
因此更新的版本起作用