如何将this.props.onClick()推迟到CSS动画完成之后? [英] How to defer this.props.onClick() until after a CSS animation is complete?
问题描述
我正在从页面中调用自定义的NanoButton
组件以及onClick
指令以路由到另一个页面:
I am calling a custom NanoButton
component from my page along with an onClick
instruction to route to another page:
// Page.js
import { Component } from 'react';
import Router from 'next/router';
class Page2 extends Component {
render() {
return(
<NanoButton type="button" color="success" size="lg" onClick={() => Router.push('/about')}>About</NanoButton>
)
}
}
单击按钮(NanoButton
组件)时,我想先执行一些内部代码,然后再进入作为道具的onClick
.通过此内部代码,我试图模拟持续600毫秒的材质设计波纹效果.这是我的方法:
When the button (NanoButton
component) is clicked, I want to execute some internal code before moving on to the onClick
coming in as props. Through this internal code, I am trying to simulate the material-design ripple effect that lasts 600 milliseconds. This is how I do it:
import { Component } from 'react';
import { Button } from 'reactstrap';
class NanoButton extends Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick(e) {
this.makeRipple(e);
this.props.onClick();
}
makeRipple(e) {
const elements = e.target.getElementsByTagName('div');
while (elements[0]) elements[0].parentNode.removeChild(elements[0]);
const circle = document.createElement('div');
e.target.appendChild(circle);
const d = Math.max(e.target.clientWidth, e.target.clientHeight);
circle.style.width = `${d}px`;
circle.style.height = `${d}px`;
const rect = e.target.getBoundingClientRect();
circle.style.left = `${e.clientX - rect.left - (d / 2)}px`;
circle.style.top = `${e.clientY - rect.top - (d / 2)}px`;
circle.classList.add('ripple');
}
render() {
return (
<Button
className={this.props.className}
type={this.props.type}
color={this.props.color}
size={this.props.size}
onClick={this.onClick}
>
{this.props.children}
</Button>
);
}
}
export default NanoButton;
因此,如您所见,我需要在this.props.onClick
之前执行makeRipple
方法.最初,它似乎并没有这样做.但是,经过进一步测试,结果证明这些方法毕竟会按正确的顺序运行,除了路由(如this.props.onClick
中所编码的)会立即发生并且样式为持续600毫秒的波纹动画没有机会跑步.使该动画发生的CSS是:
So as you can see, I need the makeRipple
method to execute before this.props.onClick
. And initially, it didn't seem to doing that. However, after further testing, it turns out that the methods do run in the right order after all, except the routing (as coded in this.props.onClick
) happens instantly and the ripple animation that's styled to last 600 milliseconds doesn't get a chance to run. The CSS that makes this animation happen is:
button {
overflow: hidden;
position: relative;
}
button .ripple {
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.7);
position: absolute;
transform: scale(0);
animation: ripple 0.6s linear;
}
@keyframes ripple {
to {
transform: scale(2.5);
opacity: 0;
}
}
如何让this.props.onClick
仅在之后播放动画?我试图像这样设置超时时间:
How do I make the this.props.onClick
run only AFTER the animation is complete? I tried setting a timeout like so:
setTimeout(this.props.onClick(), 600);
但这会引发错误.
注意:我在服务器端使用 NextJS 渲染,如果有什么区别.
Note: I'm using NextJS for server side rendering, if that makes any difference.
推荐答案
有很多方法可以做到,例如Promise
,async/await
等.
但是,如果您尝试setTimeout
,请使用
There are a lot of ways to do it, like Promise
, async/await
, etc.
But if you try setTimeout
please use
setTimeout(() => this.props.onClick(), 600);
或
setTimeout(this.props.onClick, 600);
您的情况:
setTimeout(this.props.onClick(), 600);
无效,因为此行会将this.props.onClick()
的结果传递给第一个参数,而不是传递整个函数.
won't work because this line will pass the result of this.props.onClick()
into the first param instead of passing the whole function.
这篇关于如何将this.props.onClick()推迟到CSS动画完成之后?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!