平常做移动端会用到tab选项卡,这和PC端有些区别,移动端是触摸滑动切换,PC端是点击、移入切换。

  这里滑动切换就是一个移动端事件的应用,这里主要用到的触摸事件:touchstart、touchmove、touchend。

  和做其他的效果一样,先有html结构,css样式修饰,再写JS代码。

  html:

<div class="mtabs" id="tabs"><ul class="mhead"><li>tab1</li><li>tab2</li><li>tab3</li></ul><div class="mcontent"><ul><li>tab1内容内容内容内容</li><li>tab1内容内容内容内容</li><li>tab1内容内容内容内容</li><li>tab1内容内容内容内容</li><li>tab1内容内容内容内容</li></ul><ul><li>tab2内容内容内容内容</li><li>tab2内容内容内容内容</li><li>tab2内容内容内容内容</li><li>tab2内容内容内容内容</li><li>tab2内容内容内容内容</li></ul><ul><li>tab3内容内容内容内容</li><li>tab3内容内容内容内容</li><li>tab3内容内容内容内容</li><li>tab3内容内容内容内容</li><li>tab3内容内容内容内容</li></ul></div>
</div><!-- End .mtabs -->

View Code

  css:

body,div,ul,li{margin:0;padding:0;
}
ul,li {list-style:none;
}
body {font-size:100%;font-family:Helvetica,STHeiti,Droid Sans Fallback;
}
.mtabs {width:100%;overflow:hidden;
}
.mhead {height:38px;border-top:2px solid #9ac7ed;background:#ECF2F6;-webkit-tap-highlight-color:rgba(0,0,0,0);
}
.mhead li {position:relative;font-size:1.125em;text-align:center;float:left;width:64px;height:38px;line-height:38px;color:#2a70be;
}
.mhead li.current {border-top:2px solid #2a70be;margin-top:-2px;background:#FFF;color:#c14545;
}
.mcontent {width:100%;overflow:hidden;
}
.mcontent ul {width:100%;float:left;
}
.mcontent li {height:35px;line-height:35px;font-size:1.125em;padding:0 10px;
}

View Code

  下面的截图是想要的一个效果预览:

  

  下面是实际效果,可以在Chrome的移动模式查看:

  • tab1
  • tab2
  • tab3
  • tab1内容内容内容内容
  • tab1内容内容内容内容
  • tab1内容内容内容内容
  • tab1内容内容内容内容
  • tab1内容内容内容内容
  • tab2内容内容内容内容
  • tab2内容内容内容内容
  • tab2内容内容内容内容
  • tab2内容内容内容内容
  • tab2内容内容内容内容
  • tab3内容内容内容内容
  • tab3内容内容内容内容
  • tab3内容内容内容内容
  • tab3内容内容内容内容
  • tab3内容内容内容内容

  先贴上JS代码,供参考

/*** LBS mTabs* Date: 2014-5-10* ===================================================* opts.mtab  tabs外围容器/滑动事件对象(一个CSS选择器)* opts.mhead   tabs标题容器/点击对象(一个CSS选择器)* opts.mcontent  tabs内容容器/滑动切换对象(一个CSS选择器) * opts.index  tabs索引(默认0) 指定显示哪个索引的标题、内容* opts.current  tabs当前项的类名(默认current)* ===================================================
**/
;(function(){
window.mTabs = function(opts){if(typeof opts === undefined) return;//取得tabs外围容器、标题容器、内容容器this.mtab = document.querySelector(opts.mtab);this.mhead = document.querySelector(opts.mhead);this.mcontent = document.querySelector(opts.mcontent);//取得标题容器内选项集合、内容容器内容集合this.mheads = this.mhead.children;this.mcontents = this.mcontent.children;this.length = this.mheads.length;if(this.length < 1) return;if(opts.index > this.length-1) opts.index = this.length-1;this.index = this.oIndex = opts.index || 0;this.current = opts.current || 'current'; //当前活动选项类名this.touch = {};//自定义一个对象 用来保存手指触摸相关信息this.init();
}
mTabs.prototype = {init: function(opts){this.set();this.initset();this.bind();},initset: function(){for(var i = 0; i < this.length; i++){this.mheads[i].index = i;//设置了一个属性 方便点击时判断是点了哪一项this.mheads[i].className = this.mheads[i].className.replace(this.current,'');this.mcontents[i].className = this.mcontents[i].className.replace(this.current,'');}//初始化设置、先清空手动加在标题或内容HTML标签的当前类名(this.current)、再设置哪一项为当前选项并设置类名this.mheads[this.index].className += ' '+this.current;this.mcontents[this.index].className += ' '+this.current;          //对应的内容要显示在可视区域//this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translateX(" + (-this.index * this.width) + "px)";//this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translate3d(" + (-this.index * this.width) + "px,0,0)";},set: function(){//获取浏览器的视口宽度、并设置内容容器的宽度、每一项内容区域的宽度,屏幕旋转,浏览器窗口变换会再次设置这些值this.width =  document.documentElement.clientWidth || document.body.clientWidth;this.mcontent.style.width = this.length * this.width + 'px';     for(var i = 0; i < this.length; i++) this.mcontents[i].style.width = this.width + 'px';//调整在可视区域显示的内容项//this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translateX(" + (-this.index * this.width) + "px)";this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translate3d(" + (-this.index * this.width) + "px,0,0)";},bind: function(){         //绑定各种事件var _this = this;this.mtab.addEventListener("touchstart",function(e){_this.touchStart(e);}, false);this.mtab.addEventListener("touchmove",function(e){_this.touchMove(e);}, false);this.mtab.addEventListener("touchend",function(e){_this.touchEnd(e);}, false);this.mtab.addEventListener("touchcancel",function(e){_this.touchEnd(e);}, false);this.mhead.addEventListener("click",function(e){_this.touchClick(e);}, false);this.mcontent.addEventListener('webkitTransitionEnd',function(){_this.transitionEnd();}, false);window.addEventListener("resize", function(){setTimeout(function(){_this.set();},100);}, false);window.addEventListener("orientationchange",function(){setTimeout(function(){_this.set();},100);}, false);},touchStart: function(e){this.touch.x = e.touches[0].pageX;this.touch.y = e.touches[0].pageY;this.touch.time = Date.now();this.touch.disX = 0;this.touch.disY = 0;this.touch.fixed = ''; //重要 这里采用了判断是滚动页面行为、还是切换选项行为 如果是滚动页面就在滑动时只滚动页面 相应的切换选项就切换不会滚动页面 },touchMove: function(e){if(this.touch.fixed === 'up') return;e.stopPropagation();if(e.touches.length > 1 || e.scale && e.scale !== 1) return;this.touch.disX = e.touches[0].pageX - this.touch.x;this.touch.disY = e.touches[0].pageY - this.touch.y;if(this.touch.fixed === ''){//行为判断 采用这种方式 主要解决手指按下移动(左上、右上)时滑动切换和滚动页面同时执行的问题  if( Math.abs(this.touch.disY) > Math.abs(this.touch.disX) ){this.touch.fixed = 'up';}else{this.touch.fixed = 'left';}}if(this.touch.fixed === 'left'){e.preventDefault();if( (this.index === 0 && this.touch.disX > 0) || (this.index === this.length-1 && this.touch.disX < 0) ) this.touch.disX /= 4; //在 第一项向右滑动、最后一项向左滑动 时//this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translateX(" + ( this.touch.disX - this.index * this.width ) + "px)";this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translate3d(" + ( this.touch.disX - this.index * this.width ) + "px,0,0)";} },touchEnd: function(e){ if(this.touch.fixed === 'left'){var _this = this, X = Math.abs(this.touch.disX);this.mcontent.style.webkitTransition = this.mcontent.style.transition = 'all 100ms';if( (Date.now() - this.touch.time > 100 && X > 10) || X > this.width/2 ){this.touch.time = Date.now();this.touch.disX > 0 ? this.index-- : this.index++;this.index < 0 && (this.index = 0);this.index > this.length - 1 && (this.index = this.length - 1);if(this.index === this.oIndex) this.mcontent.style.webkitTransition = this.mcontent.style.transition = 'all 300ms';if(this.index !== this.oIndex) this.replace();}//this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translateX(" + (-this.index * this.width) + "px)";this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translate3d(" + (-this.index * this.width) + "px,0,0)";}   },transitionEnd: function(){this.mcontent.style.webkitTransition = this.mcontent.style.transition = 'all 0ms';},touchClick: function(e){var target = e.target;if(target.nodeType === 1 && target.index !== undefined){if(target.index === this.index) return;e.preventDefault();e.stopPropagation();this.index = target.index;this.mcontent.style.webkitTransition = this.mcontent.style.transition = 'all 100ms';//this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translateX(" + (-this.index * this.width) + "px)";this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translate3d(" + (-this.index * this.width) + "px,0,0)";this.replace();}},replace: function(){this.mheads[this.index].className += ' '+this.current;this.mheads[this.oIndex].className = this.mheads[this.oIndex].className.replace(this.current,'').trim();this.mcontents[this.index].className += ' '+this.current;this.mcontents[this.oIndex].className = this.mcontents[this.oIndex].className.replace(this.current,'').trim();this.oIndex = this.index;}
}
}());

  使用方式很简单,如下

document.addEventListener('DOMContentLoaded',function(){//use mTabsnew mTabs({mtab: '#tabs',mhead: '#tabs .mhead',mcontent: '#tabs .mcontent'});/*new mTabs({mtab: '#tabs',mhead: '#tabs .mhead',mcontent: '#tabs .mcontent',index: 1,current: 'active'});*/},false);
mtab:
<div class="mtabs" id="tabs">//..
</div>
mhead:
<ul class="mhead">//..
</ul>
mcontent:
<div class="mcontent">//..
</div> 

  在此说下思路:

    先获得一个tabs容器对象(mtab),它包含了两个对应的类集合容器,一个是标签栏(mhead)、一个是内容栏(mcontent),再分别取得类集合容器里面对应的选项mheads、mcontents。

this.mtab = document.querySelector(opts.mtab);
this.mhead = document.querySelector(opts.mhead);
this.mcontent = document.querySelector(opts.mcontent);this.mheads = this.mhead.children;
this.mcontents = this.mcontent.children;

    获取设备浏览器窗口的宽,并更新内容容器(mcontent)的宽,内容项的宽,一般在页面都会有文档声明 <!DOCTYPE html> document.documentElement.clientWidth 就能获取浏览器窗口的宽。

this.width =  document.documentElement.clientWidth || document.body.clientWidth;
this.mcontent.style.width = this.length * this.width + 'px';
for(var i = 0; i < this.length; i++) this.mcontents[i].style.width = this.width + 'px';

    在手指触摸按上时(在tabs容器对象上), 获取手指按下时在页面的位置 ( e.touches[0].pageX)。 touchs想象成有几根手指,只需要第一根按下的手指( touches[0] )。初始化了一个行为判断 this.touch.fixed (当在tabs上滑动时是要滚动页面还是要切换选项卡)。

this.touch.x = e.touches[0].pageX;
//..
this.touch.fixed = '';

  在移动手指时,做出行为的判断。先获得移动的距离(左右方向、上下方向),根据两个方向的值比较判断是哪种行为。

this.touch.disX = e.touches[0].pageX - this.touch.x;
this.touch.disY = e.touches[0].pageY - this.touch.y;
//..
if(this.touch.fixed === ''){if( Math.abs(this.touch.disY) > Math.abs(this.touch.disX) ){this.touch.fixed = 'up';}else{this.touch.fixed = 'left';}
}

  在移动手指时,内容容器(mcontent)也会跟着移动,并且做了在处于第一项和最后一项时的移动限制。

if( (this.index === 0 && this.touch.disX > 0) || (this.index === this.length-1 && this.touch.disX < 0) ) this.touch.disX /= 4; 

  在手指离开屏幕的时候,做出切换判断,是向左还是向右。在第一项时,不能向左切换,最后一项时不能向右切换。

this.touch.disX > 0 ? this.index-- : this.index++;
this.index < 0 && (this.index = 0);
this.index > this.length - 1 && (this.index = this.length - 1);

  最后是真正的移动切换,用了css3动画切换,translateX 或者 translate3d .

//this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translateX(" + (-this.index * this.width) + "px)";
this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translate3d(" + (-this.index * this.width) + "px,0,0)";

 代码中有个transitionEnd方法,配合webkitTransitionEnd事件在动画切换执行完成时调用。这里调用这个方法是用来清除动画定义的持续时间。

transitionEnd: function(){this.mcontent.style.webkitTransition = this.mcontent.style.transition = 'all 0ms';
}this.mcontent.addEventListener('webkitTransitionEnd',function(){_this.transitionEnd();
}, false);

  点击切换是判断点击了哪一项,在初始设置时已经为每一项保存了索引值(index),根据对应的索引值,切换选项,更新状态。可以循环绑定点击事件,也可以使用事件委托,这里使用的是事件委托。

this.mheads[i].index = i;touchClick: function(e){var target = e.target;if(target.nodeType === 1 && target.index !== undefined){//..this.index = target.index;//..this.mcontent.style.webkitTransform = this.mcontent.style.transform = "translate3d(" + (-this.index * this.width) + "px,0,0)";}
}this.mhead.addEventListener("click",function(e){_this.touchClick(e);
}, false);

  tab选项卡主要是获得两组对应的类似集合(一组标签,一组内容),两个类似数组都有索引值(数组下标),通过这个索引值,做出对应的切换。获取索引值是tab选项卡的关键,移动web端的选项卡主要是增加了触摸事件操作这个索引值。加上定时器,每隔多少时间增加或者减少这个索引值,自动播放也就完成了。会了tab选项卡也就会了图片的切换,焦点图什么的,原理都是一样。

   tab选项卡下载

转载于:https://www.cnblogs.com/eyeear/p/4613643.html

移动web:tab选项卡相关推荐

  1. 异步数据加载和Tab选项卡

    开发工具与关键技术:VS echart和layui tab 作者:微凉之夏 撰写日期:2019年06月06日 在echarts入门示例中的数据是在初始化后,setOption中直接填入的,但是很多时候 ...

  2. 动感效果的TAB选项卡 jquery 插件

    动感效果的TAB选项卡 jquery 插件 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &q ...

  3. 【Android UI设计与开发】第11期:顶部标题栏(二)ActionBar实现Tab选项卡和下拉导航列表

    转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/9050573  在上一篇文章中,我们只是大概的了解了一下关于ActionBar ...

  4. 用fieldset标签轻松实现Tab选项卡效果

    fieldset是一个不常用的HTML标签,它可以将表单内的元素分组显示,legend标签为 fieldset 元素定义标题.由于各浏览器在显示fieldset和legend结构时会自动为其添加边框和 ...

  5. layui tab选项卡外部html页面,layui的Tab选项卡知识

    layui的公共类: lay-filter=" " 事件过滤器.你可能会在很多地方看到他,他一般是用于监听特定的自定义事件.你可以把它看作是一个ID选择器 layui的公共属性: ...

  6. html tab选项卡 控件,tab选项卡插件

    这是一款使用十分方便的.为移动设备定制的.可在水平和垂直两个方向上显示的jQuery和css3响应式tab选项卡插件.在你要显示很多不同的内容时,tab选项卡导航方式是十分有用的.常见的方式是在同一个 ...

  7. iOS开发-iPad侧边栏Tab选项卡切换

    Android中习惯了叫侧边栏,iOS中如果不习惯侧边栏称呼的话可以叫dock,侧边栏的切换,类似于Android中的底部导航栏的切换,iPad尺寸大了一些,导航的栏目放在侧边会显示的更好耐看一些.选 ...

  8. ViewPager+Fragment实现TabHost,Fragment动态添加、删除,Tab选项卡跟随滑动

    效果图: 代码功能: (1)用ViewPager+Fragment实现TabHost,ViewPager的每一个Page均是Fragment.ViewPager中的Fragment可以动态添加.删除. ...

  9. 漂亮的jQuery tab选项卡插件

    清远大学城网(http://www.qydxc.com) tab选项卡在实际应用中几乎到处可见,像现在大型网站163,QQ,新浪,淘宝都使用了tab选项卡效果,下面我来介绍一款jQuery tab选项 ...

  10. MUI tab选项卡之间的切换和数据获取

    查看mui官网上面的例子,会看到有多种tab 选项卡的例子,我就写下我用到的tab选项卡.写了个简单的例子,效果如下图 主页面的代码 <nav class="mui-bar mui-b ...

最新文章

  1. 移动端大图缩放模糊_关于移动端小图标模糊问题的解决方法
  2. 算法导论Java实现-构建MaxHeap
  3. PyQt5 技巧篇-增加一个类级变量,类级变量的设置方法,类级“常量“设置方法
  4. 2022年美国大学生数学建模竞赛各题型常见参考代码汇总
  5. linux ntptime(Network Time Protocol 网络时间协议)
  6. Django框架(十八)—— auth框架:用户登录、注册、认证
  7. Tailwind CSS 是一个工具集 CSS 框架
  8. verilog时钟翻转怎么写_verilog实时可调时钟代码
  9. 理解JS的6种继承方式
  10. oracle迁移mysql验证_ORACLE 迁移MYSQL 随笔
  11. 像冠军一样创建报告! Reporting Services的提示和技巧
  12. Redis 订阅与发布
  13. ad20如何画出pcb板大小_PCB板过孔对高频信号传输的影响,一定要重视
  14. Go语言实战-golang操作Mongodb
  15. linux 启动禁用显卡驱动,Linux secure boot(安全启动)时添加Nvidia显卡驱动
  16. linux双线双网卡双ip双网关设置方法,Linux双线双网卡双IP双网关设置方法
  17. matlab solve 矩阵,在Matlab中求解矩阵DAE系统
  18. 《谁动了我的奶酪》读后感 他人感悟
  19. python学习笔记(13)数据结构
  20. iframe基本使用

热门文章

  1. C++ std :: fill()函数
  2. 区块链 以太坊 合约 创建、执行 详解
  3. linux内核配置usb虚拟串口,霍尼韦尔是否能提供USB串口仿真的Linux驱动程序?
  4. 广工c语言试卷504,广工C语言试卷与答案.doc
  5. java队列 notify_java使用线程做一个消息队列,wait,notify
  6. 项目4:抽奖程序 分时间段(按时段设置的奖品数为概率)
  7. C语言w10输入法打不出中文,win10系统输不了中文怎么办
  8. mysql自动去重_关于mysql自联去重的一些记录
  9. 封装条形码MaHelper
  10. CodeForces - 786B Legacy (线段树+DIjkstra+思维)