二十七、HTML5单页框架View.js介绍 - 视图切换动画

不需要 Npm 的单页应用框架:

View.js - http://view-js.com


视图切换动画,是指活动视图发生变化,从一个视图切换至另外一个视图的过程中展现给用户的动画效果。
我们来看两个例子:

动画1(点击体验)

在这里插入图片描述

动画2(点击体验)

在这里插入图片描述
开发者也可以选择不应用动画,效果如下图所示:
在这里插入图片描述

通过对比,我们可以清晰地观察到:动画点缀会使得视图切换生动许多。那么,我们该如何开发视图切换动画呢?

通常情况下,开发者需要按照如下流程完成视图切换动画的开发:

  1. 使用css,借助 animation、transition 等属性创建视图离开动画、视图进入动画
  2. 『有条件地』引用动画并确定动画播放时长
  3. 在页面就绪时调用View.js提供的 View.setSwitchAnimation 方法,以设置动画的『播放触发器』

以下是动画2的源码(已在注释中详细描述各个步骤的执行)。

HTML
<!-- 视图1的DOM骨架 -->
<section id = "page1" data-view = "true" data-view-default = "true" >
	<header>
		<span class = "nav-back" data-view-rel = ":back"></span>
		Page 1
	</header>
	<h1>This is page 1.</h1>
	<div data-view-rel = "page2" class = "btn">Navigate to page 2.</div>
</section>

<!-- 视图2的DOM骨架 -->
<section id = "page2" data-view = "true">
	<header>
		<span class = "nav-back" data-view-rel = ":back"></span>
		Page 2
	</header>
	<h1>This is page 2.</h1>
	<div data-view-rel = "page3" class = "btn">Navigate to page 3.</div>
</section>

<!-- 视图3的DOM骨架 -->
<section id = "page3" data-view = "true">
	<header>
		<span class = "nav-back" data-view-rel = ":back"></span>
		Page 3
	</header>
	<h1>This is page 3.</h1>
	<div data-view-rel = ":default-view" class = "btn">Navigate to page 1.</div>
</section>

DOM骨架定义了视图的基本结构。开发视图骨架是使用View.js开发视图的第一要务。

CSS
/**
 * 定义动画
 */
@keyframes hideToLeft{
	from{transform: translate3d(0, 0, 0); opacity: 1;}
	to{transform: translate3d(-50%, 0, 0); opacity: 1;}
}
@keyframes showFromRight{
	from{transform: translate3d(100%, 0, 0); opacity: 1;}
	to{transform: translate3d(0, 0, 0); opacity: 1;}
}
@keyframes hideToRight{
	from{transform: translate3d(0, 0, 0); opacity: 1;}
	to{transform: translate3d(100%, 0, 0); opacity: 1;}
}
@keyframes showFromLeft{
	from{transform: translate3d(-50%, 0, 0); opacity: 1;}
	to{transform: translate3d(0, 0, 0); opacity: 1;}
}

/**
 * 视图容器水平居中
 */
[data-view-container]{
	position: relative;
	margin: 0 auto;
}
/**
 * 所有视图重叠在一起,默认都不显示
 */
*[data-view=true] {
	opacity: 0;
	z-index: 0;
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	box-sizing: border-box;
	overflow: auto;
	-webkit-overflow-scrolling: touch;
	background: #F3F3F3;
	box-shadow: 0 0 70px rgba(0, 0, 0, 0.3);
}
/**
 * 视图隐藏时要呈现的半透明黑色蒙层。默认不显示
 */
*[data-view=true]:before{
	opacity: 0;
	content: "";
	display: none;
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	background: rgba(0, 0, 0, 0.3);
}
/**
 * 活动视图可见
 */
*[data-view=true].active {
	opacity: 1;
	z-index: 1;
}

/**
 * 有条件地引用动画
 */


/* 视图含有hideToLeft样式类时播放hideToLeft动画 */
.view.hideToLeft{
	animation: hideToLeft 0.6s ease-out;
}
/* 视图向左隐藏时逐渐显示半透明黑色蒙层 */
.view.hideToLeft:before{
	display: block;
	animation: fadeIn 0.6s linear;
}

/* 视图含有showFromLeft样式类时播放showFromLeft动画 */
.view.showFromLeft{
	animation: showFromLeft 0.6s ease-out;
}
/* 视图取消隐藏时逐渐关闭半透明黑色蒙层 */
.view.showFromLeft:before{
	display: block;
	animation: fadeOut 0.6s linear;
}

/**
 * 视图含有hideToRight样式类时播放hideToRight动画。
 * z-index要比活动视图的1更高,从而使其不会被活动视图覆盖
 */
.view.hideToRight{
	z-index: 2;
	animation: hideToRight 0.6s ease-out;
}

/* 视图含有showFromRightn样式类时播放showFromRightn动画 */
.view.showFromRight{
	animation: showFromRight 0.6s ease-out;
}

其中

  1. fadeOuthideToLefthideToRight 定义了视图的离开动画,亦即视图由活动状态变为非活动状态时要执行的动画;
  2. fadeInshowFromRightshowFromeLeft 定义了视图的进入动画,亦即视图由非活动状态变为活动状态时要执行的动画;
  3. .view.hideToLeft.view.hideToRight 定义了视图离开动画的播放时机:在视图根节点DOM元素含有对应样式类时播放动画;
  4. .view.showFromLeft.view.showFromeRight 定义了视图进入动画的播放时机:在视图根节点DOM元素含有对应样式类时播放动画;
JS
;(function(){
	var timer;

	/**
	 * 动画持续时长,需要与css中定义的动画时长一致
	 * @type {number}
	 */
	var animationDuration = 600;

	/**
	 * 清除给定DOM元素上声明的动画样式
	 * @param {HTMLElement} obj
	 */
	var clear = function(obj){
		if(!obj)
			return;

		"hideToLeft, showFromRight, hideToRight, showFromLeft".split(/\s*,\s*/).forEach(function(className){
			obj.classList.remove(className);
		});
	};

	/**
	 * @param {HTMLElement} srcElement 视图切换时,要离开的当前视图对应的DOM元素。可能为null
	 * @param {HTMLElement} tarElement 视图切换时,要进入的目标视图对应的DOM元素
	 * @param {String} type 视图切换方式
	 * @param {Function} render 渲染句柄
	 */
	View.setSwitchAnimation(function(srcElement, tarElement, type, render){
		/**
		 * 动画播放前清除可能存在的动画样式
		 */
		clear(srcElement);
		clear(tarElement);

		/**
		 * 调用View.js传递而来的渲染句柄,完成活动视图的切换,包括:
		 * 1. 视图参数的传递
		 * 2. 活动视图样式类的切换
		 * 3. leave,ready、enter等事件的触发
		 */
		render();

		var isNav = type === View.SWITCHTYPE_VIEWNAV,
			isChange = type === View.SWITCHTYPE_VIEWCHANGE,
			isHistoryBack = type === View.SWITCHTYPE_HISTORYBACK,
			isHistoryForward = type === View.SWITCHTYPE_HISTORYFORWARD;

		if(isHistoryForward || isNav){
			/**
			 * 视图切换动作是“压入堆栈”的方式(浏览器前进,或代码触发)
			 */

			srcElement.classList.add("hideToLeft");
			tarElement.classList.add("showFromRight");
		}else{
			/**
			 * 视图切换动作是“弹出堆栈”的方式(浏览器后退)
			 */

			srcElement.classList.add("hideToRight");
			tarElement.classList.add("showFromLeft");
		}

		/**
		 * 动画播放完成后清除动画样式
		 */
		clearTimeout(timer);
		timer = setTimeout(function(){
			clear(srcElement);
			clear(tarElement);
		}, animationDuration);
	});
})();

其中 View.setSwitchAnimation() 用于向View.js提供『播放触发器』,告知View.js在何时播放什么动画:

  1. 压入堆栈时,源视图向左滑动隐藏,目标视图从右向左显示
  2. 弹出堆栈时,源视图向右滑动隐藏,目标视图从左向右显示

其中,『压入堆栈式』的视图切换可能由如下几种行为触发:

  1. 开发者调用API:View.navTo({String} targetViewId:目标视图ID)
  2. 开发者调用API:View.forward() - 向前查阅视图,等同于 history.forward()
  3. 用户点击声明有data-view-rel属性的元素,且data-view-rel-type 取值为 nav(没有声明 data-view-rel-type 属性时,默认为nav
  4. 用户点击浏览器中的前进按钮

『替换堆栈式』的视图切换则由如下几种行为触发:

  1. 开发者调用API:View.changeTo({String} targetViewId:目标视图ID)
  2. 用户点击声明有data-view-rel属性的元素,且data-view-rel-type 取值为 change(没有声明 data-view-rel-type 属性时,默认为nav

有关视图跳转的详细介绍,请查阅 视图跳转(一)视图跳转(二)


[第一篇]
[上一篇 - 视图回退显示] [下一篇 - 识别浏览器的前进与后退]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值