React使用定时器自动切换图片
原创
©著作权归作者所有:来自51CTO博客作者流年若逝的原创作品,请联系作者获取转载授权,否则将追究法律责任
目录
1. 效果展示
2. 需求分析
最近在学习React框架的时候,做的项目有一个需求就是如何将多张图片依次播放出来,当时的想法是使用轮播图去实现播放,但是这里有一个问题来了:如果我们的图片数量低于20张以下的话效果还是可以的,如果我们图片的数量较多的话,那使用轮播图效率就显得低下,这时我的这个想法就立即pass。
既然,轮播图这种方式不行,有没有其他方法替代呢?这里我到百度和谷歌上找了个遍,终于看到了一种适合我的需求的技术,那就是使用定时器。
2.1 定时器
关于js中定时器我们只需要知道这两个函数就可以:
1)setInterval()
setInterval() :按照指定的周期(以毫秒计)来调用函数或计算表达式。
方法会不停地调用函数,直到 clearInterval()
2)setTimeout()
相关知识点可参考:js定时器
2.2 实现思路
上面说了一大堆,就是为了表达自己在碰到这种技术难题的一种解决方法,下面就是开始自己如何实现。
首先,我自己参考了文献1里面的那片文章,里面提到了使用JS定时器实现图片切换,但是看了下觉得思路还是可以的,但是因为自己JS学的不多里面使用到的window.onload = function()直接用到React中出现了一些语法不同的问题,自己网上找了些许没搞明白,所以暂时汲取它的思路,看看网上还有其他的关于React的版本的例子?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>定时器</title>
<script type="text/javascript">
window.onload = function(){
var img = document.getElementById("img");
var imgArr = ["img/01.jpg", "img/02.jpg", "img/03.jpg", "img/04.jpg", "img/05.jpg", "img/06.jpg"];
var index = 0;
var timer;
var btn1 = document.getElementById("btn1");
btn1.onclick = function(){
clearInterval(timer);
timer = setInterval(function(){
index ++;
index = index % imgArr.length;
img.src = imgArr[index];
},1000);
}
var btn2 = document.getElementById("btn2");
btn2.onclick = function(){
clearInterval(timer);
}
}
</script>
</head>
<body>
<img src="img/01.jpg" id="img" style="width: 300px;"/><br />
<button id="btn1">开始</button>
<button id="btn2">停止</button>
</body>
</html>
好家伙,经过一下午的努力搜寻,终于看到了一个好例子如下:
renderRadar = () => {
clearInterval(radarTimer);
if (this.state.isPlayRadar) {
radarTimer = setInterval(() => {
this.setState({
radarImg: images[this.currentIndex],
craImg: this.currentIndex === 0 ? convection['iso'][0].imgUrl : convection['iso'][Math.ceil(this.currentIndex/10)-1].imgUrl
})
if (this.currentIndex < images.length-1) {
this.currentIndex += 1;
} else {
this.currentIndex = 0;
}
}, 200)
}
}
我来解释下为什么这个例子好,其实我并没有用到他里面的代码,只是看到了其中的 if (this.state.isPlayRadar)
这句代码给了我一个很大的启示,因为我前面说了,我需要将图片单张依次切换,但是我的图片又不能无限制的循环下去,所以需要设置一个判断当图片遍历完成后就停止。
2.3 代码
import React from 'react'
import { Layout, Divider } from 'antd'
import CustomBreadcrumb from '@/components/CustomBreadcrumb'
import '@/style/dlg.scss'
import img1 from '@/assets/images/1.jpg'
import img2 from '@/assets/images/2.jpg'
import img3 from '@/assets/images/3.jpg'
import img4 from '@/assets/images/4.jpg'
import img5 from '@/assets/images/5.jpg'
class DLGView extends React.Component {
constructor(pros){
super(pros);
this.state = {
imgs:[img1, img2, img3, img4,img5], // 图片数组
isPlayRadar: true, //是否需要播放
timer: null, // 定时器
show: false, // 前后按钮显示
index: 0,//显示第几个图片
tempSrc:img1,//默认初始为第一张图片
}
}
start = () =>{
let {timer, isPlayRadar} = this.state;
clearInterval(timer);
if(isPlayRadar){
timer = setInterval(() => {
this.state.index ++;
this.state.index = this.state.index % this.state.imgs.length;
this.setState({
tempSrc:this.state.imgs[this.state.index]
});
if (this.state.index >= this.state.imgs.length - 1 ) {
console.log('执行到了这里')
this.setState({
isPlayRadar: false,
})
}
//这句话不能少,否则无法停止掉
clearInterval(timer);
}, 2000); //设定2000ms切换一张
}
}
stop = () => { //重新加载一次
let {timer} = this.state;
clearInterval(timer);
this.setState({
isPlayRadar:true,
index:0
})
}
render() {
return(
<Layout>
<div>
<CustomBreadcrumb arr={['数据安全', '攻击', '数据集重建攻击','DLG'] }></CustomBreadcrumb>
</div>
<div className="ReactCarousel">
<img src={this.state.tempSrc} id="img" style={{maxWidth:500, height:'auto'}}/>
<br />
<button id="btn2" onClick={this.stop}>再次演示</button>
</div>
</Layout>
)
}
}
export
2.4 补充
上面的代码基本就能实现我所需要的功能了,这里我之前碰到的一个问题就是,在React里面将src赋值到`里面,使用下面这种方式:
this.state.img.src = this.state.imgs[this.state.index];
就会出现下面错误
TypeError: Cannot set property 'src'
所以我才换成代码里面的这种写法:
this.setState({
tempSrc:this.state.imgs[this.state.index]
});
其次就是自己写写代码时的一个小错误:
将this.stop 写成了this.stop(),然后出现了下面这个错误:
ReactJS: Maximum update depth exceeded error
解决办法就是将stop()改为this.stop
<button id="btn2" onClick={this.stop}>再次演示</button>
3. 参考文献
1. 用JS实现图片切换、定时器、轮播图
2. React使用定时器切换图片