我有一个表示按钮的react组件,该按钮根据某些props
更改内容和颜色。如果表单组件包含此按钮并提交,则该按钮将更改其内容和颜色。效果很好。
现在,我需要一个动画(CSS过渡)来改变按钮的内容。 为不同的状态设置一个明确的width
是不可行的,因为该应用程序是多语言的。使用max-width
时,动画仅在按钮扩展时起作用,而在按钮减小时不起作用。
这是一个带有按钮组件的代码段,它每秒都会更改状态。就像在实际组件中一样,此人使用引导btn
类:
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {status: 0};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
tick() {
let status = this.state.status;
status++;
if(status >= 2) {
status = 0;
}
this.setState({
status: status
});
}
render() {
const btnClass = this.state.status ? 'primary' : 'secondary';
return (
<button className={`btn btn-${btnClass}`} type='button'>
{this.state.status ? this.props.large : this.props.short}
</button>
);
}
}
// Render it
ReactDOM.render(
<Button large='This is a long button you can click on!' short='short'/>,
document.getElementById('react')
);
.btn {
-webkit-transition: width 1s; /* Safari */
transition: max-width 1s;
width: auto;
}
.btn-primary {
max-width: 300px;
}
.btn-secondary {
max-width: 50px;
}
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
width
的动画(当按钮再次变小时)?请考虑答案并不仅限于CSS。我想到了react组件会计算它的宽度,然后将其设置在componentWillMount
函数中,但这也不起作用...
答案 0 :(得分:3)
尝试将width: 100%
设置为.btn
类。为max-width
属性设置动画没有错。当文本从小文本变为大文本时,就会出现问题,浏览器将不得不重新计算auto
作为width
属性值的含义。看来100%
的工作方式不同。
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {status: 0};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
tick() {
let status = this.state.status;
status++;
if(status >= 2) {
status = 0;
}
this.setState({
status: status
});
}
render() {
const btnClass = this.state.status ? 'primary' : 'secondary';
return (
<button className={`btn btn-${btnClass}`} type='button'>
{this.state.status ? this.props.large : this.props.short}
</button>
);
}
}
// Render it
ReactDOM.render(
<Button large='This is a long button you can click on!' short='short'/>,
document.getElementById('react')
);
.btn {
-webkit-transition: width 1s; /* Safari */
transition: max-width 1s;
width: 100%;
}
.btn-primary {
max-width: 300px;
}
.btn-secondary {
max-width: 50px;
}
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
答案 1 :(得分:1)
我有解决办法。将最小宽度添加到您的CSS类并按如下所示进行转换。
在上行动画。在下降的过程中制作动画。
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {status: 0};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
tick() {
let status = this.state.status;
status++;
if(status >= 2) {
status = 0;
}
this.setState({
status: status
});
}
render() {
const btnClass = this.state.status ? 'primary' : 'secondary';
return (
<button className={`btn btn-${btnClass}`} type='button'>
{this.state.status ? this.props.large : this.props.short}
</button>
);
}
}
// Render it
ReactDOM.render(
<Button large='This is a long button you can click on!' short='short'/>,
document.getElementById('react')
);
.btn {
-webkit-transition: width 1s; /* Safari */
transition: max-width 1s, min-width 1s;
width: auto;
}
.btn-primary {
max-width: 330px;
min-width: 230px;
}
.btn-secondary {
max-width: 60px;
min-width: 40px;
text-align: left;
}
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">