我有一个React项目,我正在尝试建立一个旋转木马。我左右两个按钮,我的旋转木马下面有一些圆圈可以单独选择幻灯片。
要更改轮播中的幻灯片,我使用间隔和超时的组合来播放幻灯片动画,并确保在用户不点击任何内容时循环运行:
changeImageTimer(index = 0) {
end = new Date().getMilliseconds();
console.info(end - start);
setTimeout(()=> {
this.addAnimation();
}, this.props.timeToChangeImage - this.props.timeOfTransitionAnimation);
animationTimeout = setTimeout(() => {
if (this.state.index >= this.props.data.length - 1) {
index = 0;
} else {
index = this.state.index + 1;
}
this.setState({index: index});
this.removeAnimation();
}, this.props.timeToChangeImage);
animationInterval = setInterval(() => {
setTimeout(()=> {
this.addAnimation();
}, this.props.timeToChangeImage - this.props.timeOfTransitionAnimation);
animationTimeout = setTimeout(() => {
if (this.state.index >= this.props.data.length - 1) {
index = 0;
} else {
index = this.state.index + 1;
}
this.setState({index: index});
this.removeAnimation();
}, this.props.timeToChangeImage);
}, this.props.timeToChangeImage);
}
选择单个幻灯片的按钮附加了此功能:
clickSelector(index) {
this.clearIntervalsAndTimers();
this.setState({index: index});
start = new Date().getMilliseconds();
timeout = setTimeout(this.changeImageTimer(index), this.props.timeToHoldPictureAfterClick);
}
正如您所看到的,我希望幻灯片保持不变,然后在一段时间后重新启动幻灯片的自动迭代。
但是,'changeImageTimer'代码在'clickSelector'函数之后立即运行,并且在设置的超时延迟后没有运行。
为什么我会有这种行为?
答案 0 :(得分:2)
这是因为参数。函数的第一个参数必须是参数引用。 希望这可以帮助 。 Why is the method executed immediately when I use setTimeout?
传递参数
setTimeout(function() {
this.changeImageTimer(index);
}, this.props.timeToHoldPictureAfterClick)
希望这有帮助
答案 1 :(得分:1)
你的超时调用一个函数,无论changeImageTimer
返回什么,你都会传递它。而是绑定函数,以便setTimeout
获得一个预先加载了args的函数。
timeout = setTimeout(this.changeImageTimer.bind(this, index), this.props.timeToHoldPictureAfterClick);
顺便说一句,如果您将超时设置为班级中的属性,则以后更容易清除它们。
this.timeout = setTimeout(this.changeImageTimer.bind(this, index), this.props.timeToHoldPictureAfterClick);
// ... later on in your code
clearTimeout(this.timeout)
答案 2 :(得分:0)
像这样修改:
timeout = setTimeout(this.changeImageTimer.bind(this,index), this.props.timeToHoldPictureAfterClick);