我们经常需要将用户切换到不同视图,切换中的动画可以让用户有更好的体验。
重点:
left
,top
这样的任何会触发布局的属性完成动画。动画的选择要改由视图切换类型来决定,例如模态对话框出现的动画和列表到详情的动画就有区别。
注意:
will-change
属性让浏览器优化动画,视图动画中我们推荐will-change: transform
这里我们实现列表视图到详情视图的切换,用户点击列表项时详情滑动出现,替换掉列表页。
要实现这个效果你需要一个包含两个视图的容器,容器设置overflwo:hidden
,这样就能保证两个视图并排也不出现水平滚动条。
容器对应的CSS如下:
.container {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
}
容器设置position: relative
是为了视图可以方便地绝对定位,然后使用transform进行移动。使用transform性能比left属性好,因为left会触发布局和重绘。
视图样式如下:
.view {
width: 100%;
height: 100%;
left: 0;
top: 0;
will-change: transform;
}
为视图transform
添加transition
能够产生很好的滑动效果,我们使用cubic-bezier
曲线来完成。
.view {
transition: transform 0.3s cubic-bezier(0.465, 0.183, 0.153, 0.946);
}
需要隐藏的视图应该translate到右边:
.details-view {
transform: translateX(100%);
}
下面添加一些JavaScript实现类的切换。
var container = document.querySelector('.container');
var backButton = document.querySelector('.back-button');
var listItems = document.querySelectorAll('.list-item');
/**
* Toggles the class on the container so that
* we choose the correct view.
**/
function onViewChange(evt) {
container.classList.toggle('view-change');
}
/**
* when you click on a list item bring on the details view
**/
for (var i = 0, len = listItems.length; i < len; ++i) {
listItems[i].addEventListener('click', onViewChange, false);
}
backButton.addEventListener('click', onViewChange, false);
最后添加必要的CSS
.view-change .list-view {
transform: translateX(-100%);
}
.view-change .details-view {
transform: translateX(0);
}
你可以扩展这个例子到多视图模式,基本理念依然不变:不可见的视图需要隐藏在屏幕外面,然后在需要的时候显示出来,并且把当前视图移除。
这里是完整的在线demo
注意:
跨浏览器实现这个效果是很有挑战性的,比如在iOS中需要添加-webkit-overflwo-scrolling: touch
来‘reenable’ fling scrolling,但是你不需要控制具体的axis。
以上的方法可以使用到其他滑动元素,例如侧边导航。唯一的区别在于你不需要移动其他视图。