前言
每当我看到原生app的各种事件、效果,Material Design官方 发布更有意义的动效设计,都在想在移动web上去实现它们。本文主要讲述如何运用angularjs和angular mobile 的 $touch
,来实现h5单页面手势滑动动效切换tab和tab内容,里面包含了主要思路和简单实例。
angular mobile的的 $touch
相关资料及详细使用说明:http://mobileangularui.com/docs/module:mobile-angular-ui.gestures/module:touch/
零、基本切换思路图
1、页面加载初始时,视口显示的是tab默认的第一条数据和第一条tab的内容。其余tab的内容用transform:tanslate3d(100%,0,0)
处理,即在视口外右侧。
2、手势切换时,当方向是向左时,则给当前tab的内容元素的盒子添加transform:translate3d(-100%,0,0)
属性样式,给下一个tab内容元素的盒子添加transform:translate3d(0,0,0)
属性样式;当方向是向右时,则给当前tab的内容元素的盒子添加transform:translate3d(100,0,0 )
属性样式,给上一个tab内容元素的盒子添加transform:translate3d(0,0,0)
属性样式。
一、$touch的使用
1、在head引入mobile-angular-ui.js
和mobile-angular-ui.gestures.js
<script src="http://sandbox.runjs.cn/uploads/rs/200/w8sootip/mobile-angular-ui.min.js"></script>
<script src="http://sandbox.runjs.cn/uploads/rs/200/w8sootip/mobile-angular-ui.gestures.js"></script>
2、注入依赖模块
angular.module('myApp', ['mobile-angular-ui.gestures']);
3、bind method in $touch
var unbindFn = $touch.bind(element, {
start: function(touchInfo, e);
move: function(touchInfo, e);
end: function(touchInfo, e);
cancel: function(touchInfo, e);
}, options);
二、实例一个模板
在开发模板的过程中,主要结合运用了AngularJS的指令知识点,而angular mobile 的 $touch
方法则通过定义自定义指令来对页面进行处理。
1、简单构建页面基本框架
htm
<body>
<div class="runoob-directive" >
<div class="tab " ng-controller="tabController">
<ul>
<li ng-repeat="tab in tabs" id="tab-{{tab.id}}" ng-class="{true:'active',flase:''}[$first]">{{tab.tabname}}</li>
</ul>
</div>
<div class="content-wrap" ng-controller="contController" >
<div class="content-list ng-touchdir" ng-repeat="contlist in contlists" ng-class="{true:'active',flase:''}[$first]" id="{{contlist.id}}">
<h1 ng-repeat="list in contlist.contentlist">{{list.text}}</h1>
</div>
</div>
</div>
</body>
css
.tab{width: 100%; position: relative;}
.tab ul{width: 100%; display: table; }
.tab ul li{display: table-cell; text-align: center; padding:10px 0;}
.tab ul li.active{border-bottom: 3px solid green;}
.content-wrap{width: 100%; height: 600px; overflow: hidden; position: relative;}
.content-list{width: 100%; height: 100%; background: #00ff00; position: absolute; top: 0; left: 0; transition:all 0.6s ease-in-out; transform: translate3d(100%,0,0); z-index: 3;}
.content-list + .content-list{ background: #ffff00;}
.content-list + .content-list + .content-list{ background: #0000ff;}
.content-list h1{color:#333}
/*主要手势部分*/
.content-list.active{transform: translate3d(0,0,0);}
.content-list.left{transform:translate3d(100%,0,0);}
.content-list.right{transform:translate3d(-100%,0,0);}
js
var Myapp = angular.module('Myapp',['mobile-angular-ui','mobile-angular-ui.gestures']);
var data = [
{
id:"tab1",
tabname:"页面1",
contentlist:[
{text:"页面1content"}
]
},
{
id:"tab2",
tabname:"页面2",
contentlist:[
{text:"页面2content"}
]
},
{
id:"tab3",
tabname:"页面3",
contentlist:[
{text:"页面3content"}
]
}
];
Myapp.controller('tabController',function($scope) {
$scope.tabs = data;
});
Myapp.controller('contController',function($scope) {
$scope.contlists = data;
});
页面雏形
三、添加手势交互这要逻辑代码
我在css样式表里添加了.active
、.left
、.right
样式名,它们分别对应的样式属性是transform: translate3d(0,0,0)
、transform: translate3d(100%,0,0)
、transform: translate3d(-100%,0,0)
css
/*主要手势部分*/
.content-list.active{transform: translate3d(0,0,0);}
.content-list.left{transform:translate3d(100%,0,0);}
.content-list.right{transform:translate3d(-100%,0,0);}
1、定义自定义指令
Myapp.directive('ngTouchdir', ['$touch', function($touch){
// Runs during compile
return {
restrict: 'C',
link: function($scope, element) {
//主要方法
}
};
}]);
2、主要方法–bind touch及逻辑处理代码
var isMove = false;//是否发生移动
$touch.bind(element, {
move: function(touch) {
var firstTag = jQuery('.content-wrap .content-list').first().hasClass('active');//第一个元素是否存在"active"选择器
var lastTag = jQuery('.content-wrap .content-list').last().hasClass('active');//最后一个元素是否存在"active"选择器
var direction = touch.direction;//判断移动方向
var moveW = Math.abs(touch.distanceX);//获取移动距离
//判断是否发生移动
if(moveW > 100){
isMove = true;
switch(direction){
case 'LEFT':
if(lastTag != true){
element.next().addClass('active');
element.next().removeClass('right left');
element.addClass('right');
element.removeClass('active left');
}
break;
case 'RIGHT':
if(firstTag != true){
element.prev().addClass('active');
element.prev().removeClass('right left');
element.addClass('left');
element.removeClass('active right');
}
break;
}
}
},
end: function(touch){
var tabLi;//即将切换的tab的id
if(isMove){
if(touch.direction == 'LEFT'){
tabLi = element.next().attr('id');
}else if(touch.direction == 'RIGHT'){
tabLi = element.prev().attr('id');
}
//如果当前是第一个或者最后一个tab,即无上一个元素或者下一个元素,那返回的值就是'undefined'
//如果为'undefined',tab的id就是当前的tab的id
tabLi = tabLi == undefined ? element.attr('id') : tabLi;
jQuery('.tab li').removeClass('active');
jQuery('#tab-' + tabLi).addClass('active');
}
isMove = false;
}
});
四、demo
demo链接:http://sandbox.runjs.cn/show/6wchgrho
demo演示: