【发布时间】:2018-02-06 12:09:09
【问题描述】:
我正在使用 React Router v4 和 react-transition-group v2 来测试页面滑动动画。
const RouterMap = () => (
<Router>
<Route render={({ location }) =>
<TransitionGroup>
<CSSTransition key={location.pathname.split('/')[1]} timeout={500} classNames="pageSlider" mountOnEnter={true} unmountOnExit={true}>
<Switch location={location}>
<Route path="/" exact component={ Index } />
<Route path="/comments" component={ Comments } />
<Route path="/opinions" component={ Opinions } />
<Route path="/games" component={ Games } />
</Switch>
</CSSTransition>
</TransitionGroup>
} />
</Router>
)
还有 CSS:
.pageSlider-enter {
transform: translate3d(100%, 0, 0);
}
.pageSlider-enter.pageSlider-enter-active {
transform: translate3d(0, 0, 0);
transition: all 600ms;
}
.pageSlider-exit {
transform: translate3d(0, 0, 0);
}
.pageSlider-exit.pageSlider-exit-active {
transform: translate3d(-100%, 0, 0);
transition: all 600ms;
}
动画如下:
如您所见,index page 滑动到detail page 的动画是正确的(从右到左)。但是当我点击Back图标时,我希望index page从左到右出来。
我知道如果我把 CSS 改成下面这样,页面会从左到右出来:
.pageSlider-enter {
transform: translate3d(-100%, 0, 0);
}
.pageSlider-exit.pageSlider-exit-active {
transform: translate3d(100%, 0, 0);
transition: all 600ms;
}
但是如何将两个动画结合在一起呢?一般来说,当用户点击返回图标时,动画应该是from left to right。
更新:2017.08.31
感谢@MatijaG,使用路径深度确实是一个很棒的主意。我跟着它,遇到了一个新问题。
function getPathDepth(location) {
let pathArr = (location || {}).pathname.split('/');
pathArr = pathArr.filter(n => n !== '');
return pathArr.length;
}
<Route render={({ location }) =>
<TransitionGroup>
<CSSTransition
key={location.pathname.split('/')[1]}
timeout={500}
classNames={ getPathDepth(location) - this.state.prevDepth > 0 ? 'pageSliderLeft' : 'pageSliderRight' }
mountOnEnter={true}
unmountOnExit={true}
>
<Switch location={location}>
<Route path="/" exact component={ Index } />
<Route path="/comments" component={ Comments } />
<Route path="/opinions" component={ Opinions } />
<Route path="/games/lol" component={ LOL } /> // add a new route
<Route path="/games" component={ Games } />
</Switch>
</CSSTransition>
</TransitionGroup>
} />
并更新了 CSS:
.pageSliderLeft-enter {
transform: translate3d(100%, 0, 0);
}
.pageSliderLeft-enter.pageSliderLeft-enter-active {
transform: translate3d(0, 0, 0);
transition: all 600ms;
}
.pageSliderLeft-exit {
transform: translate3d(0, 0, 0);
}
.pageSliderLeft-exit.pageSliderLeft-exit-active {
transform: translate3d(100%, 0, 0);
transition: all 600ms;
}
.pageSliderRight-enter {
transform: translate3d(-100%, 0, 0);
}
.pageSliderRight-enter.pageSliderRight-enter-active {
transform: translate3d(0, 0, 0);
transition: all 600ms;
}
.pageSliderRight-exit {
transform: translate3d(0, 0, 0);
}
.pageSliderRight-exit.pageSliderRight-exit-active {
transform: translate3d(-100%, 0, 0);
transition: all 600ms;
}
动画:
从 '/' 到 '/games' 没问题,从 '/games' 回到 '/' 仍然没问题(类型 1:路由 A -> 路由 B,只有 2 个路由)。但是如果首先从'/'到'/games',然后从'/games'到'/games/lol',第二阶段失去动画(类型2:route A -> route B -> route C,3条或更多路线)。我们也看到从'/games/lol'回到'/games'再回到'/',幻灯片动画和type 1不一样。
有人知道这个问题吗?
【问题讨论】:
-
请问使用 key={location.pathname.split('/')[1]} 的原因是什么?我认为这是您对 a->b->c 的问题. (/ => undefined; /games => games; /games/lol => games ) 这意味着 /games 和 /games/lol 具有相同的键,因此不会触发动画。您应该使用 key={location.key}
-
@MatijaG,是的,你是对的。这是我的错。因为HashRouter,我使用
key={location.pathname.split('/')[1]}。 -
@MatijaG,当我深入了解这个问题时,我发现还有其他一些问题。于是我又问了一个问题:stackoverflow.com/questions/45978263/…。如果你有时间,我真的希望我能在那里得到你的帮助。无论如何,非常感谢。
标签: react-router react-transition-group