网站首页 > 知识剖析 正文
前言
最近产品有个需求,要做个tab标签切换,这最基本的样式当然不在话下,但作为极客的我总要与众不同吧!于是大开脑洞,也就想出了个tab切换时候加个滑动动画(表笑我,谁让咱没达到UI交互设计师的高度呢),再然后正好想起本站曾经有个效果(传送门),于是乎找了这个效果demo给产品看,产品欣然同意了。
那么,问题又来了,之前的这个效果有几个弊端,也是我和产品认为不好的:
不同tab页的内容高度不同,差距可能还比较大,不能用一个统一的固定高度来搞
例如从tab1跳到tab3这种跨项的情况,原则上是不能让用户在动画过程中看到tab2内容的(不要问为什么,这就是极客精神),如果从tab1跳到tab5,中间跨了3项,这体验总感觉略low啊
因此,轮子还得造!
需求功能
不固定高度。高度不同的tab页直接也可以自适应切换
跨项无缝切换。跨项切换时候不会看到中间项内容
tab标题也增加滑动动画
思路分析
所谓不固定高度,那么只有在即将动画时拿到切换前和切换后两个tab页中较大的高度进行设置
跨项不显示中间项的话,那么只有“造假”了:把切换前和切换后的两个tab页克隆下来构造个动画区,放到最前面,走个过场动画,同时隐藏掉原来真实tab页,结束后remove掉动画区,同时将真实tab页展现(本人觉得这是个简单的笨办法,如果大神有更合适的思路可以留言讨论)
代码赏析
以下是jquery插件的原代码,注释可以说的手把手的教学!每一步都写了注释,重点就是看“tab页动画部分”的注释
$.fn.extend({tab: function (index) {//index:初始化后第几个tab显示,默认0 ? ?this.each(function () { ? ? ?var animating = false;//动画进行中的标识,保证不会在动画过程中再次执行动画 ? ? ?var $this = $(this); ? ? ?var $tabCard = $this.children(".tab-card"); ? ? ?var $tabCards = $tabCard.children(); ? ? ?var $tabPaper = $this.children(".tab-paper"); ? ? ?var $tabPapers = $tabPaper.children(); ? ? ?var curIndex = $tabCards.filter(".cur").index();//通过cur获取当前tab页序号 ? ? ?curIndex = index || (curIndex == -1 ? 0 : curIndex) || 0;//参数index优先级最高 ? ? ?//初始化cur状态 ? ? ?$tabCards.removeClass("cur"); ? ? ?$tabPapers.removeClass("cur"); ? ? ?$tabCards.eq(curIndex).addClass("cur"); ? ? ?$tabPapers.eq(curIndex).addClass("cur"); ? ? ?/*************************tab标签的动画部分*************************/ ? ? ?/*此段代码借鉴lavaLamp,构造一个绝对定位的back li在滑动*/ ? ? ?$tabCard.each(function () { ? ? ? ?var b = $(this), noop = function () { ? ? ? ?}, $back = $('<li class="back"><div class="left"></div></li>').appendTo(b), $li = $("li", this), curr = $("li.cur", this)[0] || $($li[0]).addClass("cur")[0]; ? ? ? ?$li.not(".back").hover(function () { ? ? ? ? ?move(this) ? ? ? ?}, noop); ? ? ? ?$(this).hover(noop, function () { ? ? ? ? ?move(curr) ? ? ? ?}); ? ? ? ?$li.not(".back").click(function (e) { ? ? ? ? ?if (!animating) { ? ? ? ? ? ?setCurr(this); ? ? ? ? ?} ? ? ? ?}); ? ? ? ?setCurr(curr); ? ? ? ?function setCurr(a) { ? ? ? ? ?$back.css({"left": a.offsetLeft + "px", "width": a.offsetWidth + "px"}); ? ? ? ? ?curr = a ? ? ? ?} ? ? ? ?function move(a) { ? ? ? ? ?$back.each(function () { ? ? ? ? ? ?$(this).dequeue() ? ? ? ? ?}).animate({width: a.offsetWidth, left: a.offsetLeft}, 500, "easeOutBack"); ? ? ? ?} ? ? ?}); ? ? ?/*************************tab页动画部分*************************/ ? ? ?/*tab标签点击*/ ? ? ?$tabCards.on("click", function () { ? ? ? ?slide(this) ? ? ?}); ? ? ?/*直接更改当前tab标签样式*/ ? ? ?function changeCard(the) { ? ? ? ?var $t = $(the); ? ? ? ?$t.addClass("cur").siblings().removeClass("cur"); ? ? ?} ? ? ?/*直接切换tab页内容位置*/ ? ? ?function changePaper(the) { ? ? ? ?var $t = $(the); ? ? ? ?var ci = $t.index(); ? ? ? ?$tabPapers.eq(ci).addClass("cur").siblings().removeClass("cur"); ? ? ? ?curIndex = ci; ? ? ? ?$tabPaper.height($tabPapers.eq(ci).height()); ? ? ?} ? ? ?/*tab页滑动动画*/ ? ? ?function slide(the) { ? ? ? ?if (!animating) { ? ? ? ? ?var $t = $(the); ? ? ? ? ?changeCard(the); ? ? ? ? ?var ci = $t.index(); ? ? ? ? ?// 当前页和切换页相同时 直接返回 ? ? ? ? ?if (ci == curIndex) return; ? ? ? ? ?var $fromPaper = $tabPapers.eq(curIndex); ? ? ? ? ?var $toPaper = $tabPapers.eq(ci); ? ? ? ? ?//克隆一个当前页和一个切换页,后续只做动画使用 ? ? ? ? ?var $fromPaper_clone = $fromPaper.clone(); ? ? ? ? ?var $toPaper_clone = $toPaper.clone(); ? ? ? ? ?//获取tab页宽度,padding样式 ? ? ? ? ?var paperWidth = $tabPaper.width(); ? ? ? ? ?var paperPadding = $tabPaper.css("padding"); ? ? ? ? ?var paperPaddingLeft = parseInt($tabPaper.css("padding-left")); ? ? ? ? ?//通过宽度和padding计算总宽度 ? ? ? ? ?var paperWidthTotal = paperWidth + 2 * paperPaddingLeft; ? ? ? ? ?//比较当前页和切换页的高度,选取高的作为动画时的高度 ? ? ? ? ?var paperHeight = Math.max($fromPaper.height(), $toPaper.height()); ? ? ? ? ?//定义动画区样式 ? ? ? ? ?$fromPaper_clone.css({ ? ? ? ? ? ?float: "left", ? ? ? ? ? ?display: "block", ? ? ? ? ? ?background: "#fff", ? ? ? ? ? ?padding: paperPadding, ? ? ? ? ? ?width: paperWidth, ? ? ? ? ? ?height: $fromPaper.height() ? ? ? ? ?}); ? ? ? ? ?$toPaper_clone.css({ ? ? ? ? ? ?float: "left", ? ? ? ? ? ?"display": "block", ? ? ? ? ? ?background: "#fff", ? ? ? ? ? ?padding: paperPadding, ? ? ? ? ? ?"width": paperWidth, ? ? ? ? ? ?height: $toPaper.height() ? ? ? ? ?}); ? ? ? ? ?//定义动画区,此动画区只作动画使用,动画完成后立刻remove ? ? ? ? ?var $animateArea = $("<div></div>"); ? ? ? ? ?$animateArea.css({ ? ? ? ? ? ?"position": "absolute", ? ? ? ? ? ?"top": 0, ? ? ? ? ? ?left: 0, ? ? ? ? ? ?width: 2 * paperWidthTotal, ? ? ? ? ? ?height: paperHeight ? ? ? ? ?}); ? ? ? ? ?//定义动画到达的位置,比较切换页和当前页序号大小,以此决定动画是向前滑动还是向后滑动 ? ? ? ? ?var animateLeft; ? ? ? ? ?if (ci > curIndex) { ? ? ? ? ? ?$animateArea.css("left", 0).append($fromPaper_clone).append($toPaper_clone); ? ? ? ? ? ?animateLeft = -paperWidthTotal; ? ? ? ? ?} else if (ci < curIndex) { ? ? ? ? ? ?$animateArea.css("left", -paperWidthTotal).append($toPaper_clone).append($fromPaper_clone); ? ? ? ? ? ?animateLeft = 0; ? ? ? ? ?} ? ? ? ? ?//动画区被加载,同时tab页高度改变,真实tab透明隐藏 ? ? ? ? ?$tabPaper.append($animateArea); ? ? ? ? ?$tabPaper.height(paperHeight); ? ? ? ? ?$tabPapers.css({"opacity": 0, filter: "alpha(opacity=0)"}); ? ? ? ? ?//执行动画,动画结束后remove掉动画区,直接定位并显示出真实tab页内容 ? ? ? ? ?animating = true; ? ? ? ? ?$animateArea.animate({left: animateLeft}, 500, "easeOutQuint", function () { ? ? ? ? ? ?$animateArea.remove(); ? ? ? ? ? ?changePaper(the); ? ? ? ? ? ?$tabPapers.css({"opacity": 1, filter: "alpha(opacity=100)"}); ? ? ? ? ? ?animating = false; ? ? ? ? ?}); ? ? ? ?} ? ? ?} ? ?}); ?}});
效果预览~~
在线代码调试:地址
查看完整代码及详细内容:http://www.gbtags.com/gb/share/5781.htm
- 上一篇: jQuery的事件绑定
- 下一篇: jQuery 事件详解
猜你喜欢
- 2024-12-03 停止javascript的ajax请求,取消axios请求,取消reactfetch请求
- 2024-12-03 HTML5 的一些小的整理吧
- 2024-12-03 前端架构101:MVC的不足与Flux的崛起
- 2024-12-03 一篇文章搞定form表单中上传图片控件使用技巧
- 2024-12-03 Python在selenium里面注入JavaScript程序的方法
- 2024-12-03 写给前端工程师的Flutter详细教程
- 2024-12-03 vue - Vue中的ajax
- 2024-12-03 开源适用于JavaScript的Excel解析器和生成器
- 2024-12-03 使用JS把图片压缩并转成Base64的简便方法
- 2024-12-03 jQuery EasyUI使用教程:数据网格中的列运算
- 05-05vin码怎么查车型?车辆VIN码的第十位代表什么信息?
- 05-05Java数组数据的操作之检查日期格式是否正确
- 05-05苹果序列号怎么看生产日期和产地?
- 05-05参考文献中的M J N D字母代表什么?
- 05-05闲鱼交易技巧,满满的干货(闲鱼的交易流程怎么样的?我是买家)
- 05-05忘记自已多少岁了?可试试年龄计算器
- 05-05汽车-剖析、解析车架号(VIN)中的第10位-车型年份
- 05-05干货|史上最全波特酒年份指南(波特酒 年份)
- 最近发表
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)