#css #reactjs
#css #reactjs
Вопрос:
У меня есть страница с двумя разделениями. Каждый div занимает весь экран, поэтому один div в начале находится сверху и виден, в то время как другой не виден. Когда я нажимаю кнопку на первом div, я хочу, чтобы второй div вставлялся и становился видимым поверх первого div. Затем я хочу, чтобы второй div выдвинулся и снова показал первый div.
Моя проблема в том, что я не знаю, как связать javascript и css. Когда я нажимаю кнопку и запускаю событие, я не уверен, как запустить анимацию.
Реагировать
const styles = {
p1: "page1",
p2: "page2",
slideIn: "slideIn",
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
}
this.handleClick = this.handleClick.bind(this);
}
handleClick = () => {
//Make Page 2 slide in and then slide out
//Apply the class page2Visible to make page 2 visible
};
render() {
const { classes } = this.props;
return (
<React.Fragment>
<div className={`${styles.p1}`} onClick={this.handleClick}>Page 1</div>
<div className={`${styles.p2} ${styles.slideIn}`}>Page 2</div>
</React.Fragment>
);
}
}
export default withStyles(styles)(App);
CSS
.App {
margin: 0;
padding: 0;
}
.page1 {
background-color: blue;
margin:0;
padding:0;
z-index:8;
top:0;
left:0;
position:fixed;
width:100%;
height:100%;
}
.page2 {
background-color: red;
margin:0;
padding:0;
z-index:8;
top:0;
left:0;
position:fixed;
width:100%;
height:100%;
opacity: 0;
transform: translateX(-100%);
-webkit-transform: translateX(-100%);
}
.slideIn {
animation: slide-in 0.5s forwards;
-webkit-animation: slide-in 0.5s forwards;
}
.slideOut {
animation: slide-out 0.5s forwards;
-webkit-animation: slide-out 0.5s forwards;
}
@keyframes slideIn {
100% { transform: translateX(0%); }
}
@-webkit-keyframes slideIn {
100% { -webkit-transform: translateX(0%); }
}
@keyframes slideOut {
0% { transform: translateX(0%); }
100% { transform: translateX(-100%); }
}
@-webkit-keyframes slideOut {
0% { -webkit-transform: translateX(0%); }
100% { -webkit-transform: translateX(-100%); }
}
.page2Visible {
visibility: visible;
opacity: 1;
}
Комментарии:
1. просто добавьте класс с анимацией в вашем состоянии и используйте это для имени класса вашего компонента react. Затем, когда вы нажмете кнопку, обновите свое состояние, чтобы у класса было правильное имя, чтобы анимация работала. Я бы назвал это ответом, но я слишком ленив, чтобы читать весь код, и не уверен, в чем ваша проблема : )
2. вот пример: jsfiddle.net/ahmadabdul3/ax82s7hf/2 если это поможет, дайте мне знать, и я добавлю это в качестве ответа
Ответ №1:
Изначально вы должны поддерживать состояние для текущего активного div. У каждого div есть кнопка, при нажатии на которую скрывается этот конкретный div и активируется другой div. В примере кода, который я привел ниже, я задал высоту div как 500 пикселей, но вы можете указать высоту по своему усмотрению. Здесь я использую свойство перехода ease-in-out для выполнения анимации скольжения вверх и скольжения вниз. Вы можете протестировать код в https://jsfiddle.net/krishnauppili/okn4vbe0/5
Вот код React (App.js ):
class App extends Component {
constructor(props) {
super(props);
this.state = {
activeDiv: "div1",
}
}
toggleDiv = () => {
this.setState({
activeDiv: this.state.activeDiv === "div1" ? "div2" : "div1",
});
};
render() {
return (
<div className="App">
<div className={this.state.activeDiv === "div1" ? "div1 show" : "div1 hide"} id="div1">
Div 1
<button type="button" onClick={this.toggleDiv}> Hide div1</button>
</div>
<div className={this.state.activeDiv === "div2" ? "div2 show" : "div2 hide"} id="div2">
Div 2
<button type="button" onClick={this.toggleDiv}> Hide div2</button>
</div>
</div>
);
}}
Вот код CSS(App.css):
.div1{
background-color: black;
}
.div2{
background-color: green;
}
.div1,.div2{
color:white;
}
.div1.show,.div2.show{
height:500px;
transition: all 0.2s ease-in-out;
padding-top: 50px;
text-align: center;
}
.div1.hide,.div2.hide{
text-align: center;
height: 0;
overflow: hidden;
transition: all 0.2s ease-in-out;
}
Ответ №2:
у вас есть пара проблем, сначала вы должны сохранить свои классы для анимации в своем состоянии и обновить свое состояние при нажатии на синее поле. Кроме того, ваши анимации и идентификаторы ключевых кадров написаны не последовательно:
для анимации установлено значение animation: slide-in
, тогда как идентификатор ключевых кадров равен ‘slidein’ обратите внимание, что один из них — camelcase, а другой имеет прочерк. Я скопировал ваш код в jsfiddle и должен работать:https://jsfiddle.net/ahmadabdul3/y6xsveL5/22
также я изменил анимацию с translatex на свойство left, оно установлено на left: -100px
, а анимация устанавливает его на left: 0
Я обновил jsfiddle, так что страница 2 вставляется, ждет 2 секунды, затем выдвигается. Я использовал функцию обратного вызова setState и установил тайм-аут в 2 секунды, затем перенес класс из slideinв slideOut :https://jsfiddle.net/ahmadabdul3/y6xsveL5/29
затем, примерно через 600 миллисекунд, я возвращаю класс в исходное состояние без дополнительного скользящего класса. Таким образом, если вы нажмете еще раз, он снова сдвинется
Я не уверен, что обратные вызовы setState являются правильным решением, я думаю, что есть способ настроить анимацию из css, чтобы заставить ее выполнять слайд с последующим выводом.
Если вы хотите, чтобы страница 2 выдвигалась при нажатии, вы можете повторить метод handle click для страницы 1 и просто изменить класс на slide out
на самом деле я снова обновил код, потому что есть проблема, если вы нажимаете на синюю страницу во время скольжения, это отключает анимацию, потому что она обновляет класс до завершения анимации, вам нужно отслеживать, происходит ли скольжение, вы не разрешаете щелчку ничего делать, пока не будет выполнена вся анимация:https://jsfiddle.net/ahmadabdul3/y6xsveL5/35
окончательный код:
class TodoApp extends React.Component {
sliding = false;
state = {
page2Class: "",
};
handleClick = () => {
if (this.sliding) return;
this.sliding = true;
this.setState({ page2Class: 'slideIn' }, () => {
setTimeout(() => {
this.setState({ page2Class: 'in-view slideOut' }, () => {
setTimeout(() => {
this.setState({ page2Class: '' }, () => {
this.sliding = false;
});
}, 600)
});
}, 2000)
});
};
render() {
const { page2Class } = this.state;
return (
<div>
<div className='page1' onClick={this.handleClick}>Page 1</div>
<div className={`page2 ${page2Class}`}>Page 2</div>
</div>
)
}
}
css
.App {
margin: 0;
padding: 0;
}
.page1 {
background-color: blue;
margin:0;
padding:0;
z-index:8;
top:0;
left:0;
position:fixed;
width:100%;
height:100%;
}
.page2 {
background-color: red;
margin:0;
padding:0;
z-index:8;
top:0;
left:-100%;
position:fixed;
width:100%;
height:100%;
}
.in-view {
left: 0;
}
.slideIn {
animation: slideIn 0.5s forwards;
-webkit-animation: slideIn 0.5s forwards;
}
.slideOut {
animation: slideOut 0.5s forwards;
-webkit-animation: slideOut 0.5s forwards;
}
@keyframes slideIn {
100% { left: 0; }
}
@-webkit-keyframes slideIn {
100% { left: 0; }
}
@keyframes slideOut {
100% { left: 100%; }
}
@-webkit-keyframes slideOut {
100% { left: 100%; }
}
.page2Visible {
visibility: visible;
opacity: 1;
}