• 繼承Jquery的方法--tab滑動動畫切換

    1
    HTML5 jQuery CSS C/C++ Go 8492 次瀏覽

    前言

    最近產品有個需求,要做個tab標簽切換,這最基本的樣式當然不在話下,但作為極客的我總要與眾不同吧!于是大開腦洞,也就想出了個tab切換時候加個滑動動畫(表笑我,誰讓咱沒達到UI交互設計師的高度呢),再然后正好想起本站曾經有個效果(傳送門),于是乎找了這個效果demo給產品看,產品欣然同意了。

    那么,問題又來了,之前的這個效果有幾個弊端,也是我和產品認為不好的:

    1. 不同tab頁的內容高度不同,差距可能還比較大,不能用一個統一的固定高度來搞
    2. 例如從tab1跳到tab3這種跨項的情況,原則上是不能讓用戶在動畫過程中看到tab2內容的(不要問為什么,這就是極客精神),如果從tab1跳到tab5,中間跨了3項,這體驗總感覺略low啊

    因此,輪子還得造!

    需求功能

    1. 不固定高度。高度不同的tab頁直接也可以自適應切換
    2. 跨項無縫切換。跨項切換時候不會看到中間項內容
    3. tab標題也增加滑動動畫

    思路分析

    1. 所謂不固定高度,那么只有在即將動畫時拿到切換前和切換后兩個tab頁中較大的高度進行設置
    2. 跨項不顯示中間項的話,那么只有“造假”了:把切換前和切換后的兩個tab頁克隆下來構造個動畫區,放到最前面,走個過場動畫,同時隱藏掉原來真實tab頁,結束后remove掉動畫區,同時將真實tab頁展現(本人覺得這是個簡單的笨辦法,如果大神有更合適的思路可以留言討論)

    代碼賞析

    以下是jquery插件的原代碼,注釋可以說的手把手的教學!每一步都寫了注釋,重點就是看“tab頁動畫部分”的注釋

    	
    1. $.fn.extend({
    2. tab: function (index) {//index:初始化后第幾個tab顯示,默認0
    3. this.each(function () {
    4. var animating = false;//動畫進行中的標識,保證不會在動畫過程中再次執行動畫
    5. var $this = $(this);
    6. var $tabCard = $this.children(".tab-card");
    7. var $tabCards = $tabCard.children();
    8. var $tabPaper = $this.children(".tab-paper");
    9. var $tabPapers = $tabPaper.children();
    10. var curIndex = $tabCards.filter(".cur").index();//通過cur獲取當前tab頁序號
    11. curIndex = index || (curIndex == -1 ? 0 : curIndex) || 0;//參數index優先級最高
    12. //初始化cur狀態
    13. $tabCards.removeClass("cur");
    14. $tabPapers.removeClass("cur");
    15. $tabCards.eq(curIndex).addClass("cur");
    16. $tabPapers.eq(curIndex).addClass("cur");
    17. /*************************tab標簽的動畫部分*************************/
    18. /*此段代碼借鑒lavaLamp,構造一個絕對定位的back li在滑動*/
    19. $tabCard.each(function () {
    20. var b = $(this), noop = function () {
    21. }, $back = $('<li class="back"><div class="left"></div></li>').appendTo(b), $li = $("li", this), curr = $("li.cur", this)[0] || $($li[0]).addClass("cur")[0];
    22. $li.not(".back").hover(function () {
    23. move(this)
    24. }, noop);
    25. $(this).hover(noop, function () {
    26. move(curr)
    27. });
    28. $li.not(".back").click(function (e) {
    29. if (!animating) {
    30. setCurr(this);
    31. }
    32. });
    33. setCurr(curr);
    34. function setCurr(a) {
    35. $back.css({"left": a.offsetLeft + "px", "width": a.offsetWidth + "px"});
    36. curr = a
    37. }
    38.  
    39. function move(a) {
    40. $back.each(function () {
    41. $(this).dequeue()
    42. }).animate({width: a.offsetWidth, left: a.offsetLeft}, 500, "easeOutBack");
    43. }
    44. });
    45. /*************************tab頁動畫部分*************************/
    46. /*tab標簽點擊*/
    47. $tabCards.on("click", function () {
    48. slide(this)
    49. });
    50. /*直接更改當前tab標簽樣式*/
    51. function changeCard(the) {
    52. var $t = $(the);
    53. $t.addClass("cur").siblings().removeClass("cur");
    54. }
    55.  
    56. /*直接切換tab頁內容位置*/
    57. function changePaper(the) {
    58. var $t = $(the);
    59. var ci = $t.index();
    60. $tabPapers.eq(ci).addClass("cur").siblings().removeClass("cur");
    61. curIndex = ci;
    62. $tabPaper.height($tabPapers.eq(ci).height());
    63. }
    64.  
    65. /*tab頁滑動動畫*/
    66. function slide(the) {
    67. if (!animating) {
    68. var $t = $(the);
    69. changeCard(the);
    70. var ci = $t.index();
    71. // 當前頁和切換頁相同時 直接返回
    72. if (ci == curIndex) return;
    73. var $fromPaper = $tabPapers.eq(curIndex);
    74. var $toPaper = $tabPapers.eq(ci);
    75. //克隆一個當前頁和一個切換頁,后續只做動畫使用
    76. var $fromPaper_clone = $fromPaper.clone();
    77. var $toPaper_clone = $toPaper.clone();
    78. //獲取tab頁寬度,padding樣式
    79. var paperWidth = $tabPaper.width();
    80. var paperPadding = $tabPaper.css("padding");
    81. var paperPaddingLeft = parseInt($tabPaper.css("padding-left"));
    82. //通過寬度和padding計算總寬度
    83. var paperWidthTotal = paperWidth + 2 * paperPaddingLeft;
    84. //比較當前頁和切換頁的高度,選取高的作為動畫時的高度
    85. var paperHeight = Math.max($fromPaper.height(), $toPaper.height());
    86. //定義動畫區樣式
    87. $fromPaper_clone.css({
    88. float: "left",
    89. display: "block",
    90. background: "#fff",
    91. padding: paperPadding,
    92. width: paperWidth,
    93. height: $fromPaper.height()
    94. });
    95. $toPaper_clone.css({
    96. float: "left",
    97. "display": "block",
    98. background: "#fff",
    99. padding: paperPadding,
    100. "width": paperWidth,
    101. height: $toPaper.height()
    102. });
    103. //定義動畫區,此動畫區只作動畫使用,動畫完成后立刻remove
    104. var $animateArea = $("<div></div>");
    105. $animateArea.css({
    106. "position": "absolute",
    107. "top": 0,
    108. left: 0,
    109. width: 2 * paperWidthTotal,
    110. height: paperHeight
    111. });
    112. //定義動畫到達的位置,比較切換頁和當前頁序號大小,以此決定動畫是向前滑動還是向后滑動
    113. var animateLeft;
    114. if (ci > curIndex) {
    115. $animateArea.css("left", 0).append($fromPaper_clone).append($toPaper_clone);
    116. animateLeft = -paperWidthTotal;
    117. } else if (ci < curIndex) {
    118. $animateArea.css("left", -paperWidthTotal).append($toPaper_clone).append($fromPaper_clone);
    119. animateLeft = 0;
    120. }
    121. //動畫區被加載,同時tab頁高度改變,真實tab透明隱藏
    122. $tabPaper.append($animateArea);
    123. $tabPaper.height(paperHeight);
    124. $tabPapers.css({"opacity": 0, filter: "alpha(opacity=0)"});
    125. //執行動畫,動畫結束后remove掉動畫區,直接定位并顯示出真實tab頁內容
    126. animating = true;
    127. $animateArea.animate({left: animateLeft}, 500, "easeOutQuint", function () {
    128. $animateArea.remove();
    129. changePaper(the);
    130. $tabPapers.css({"opacity": 1, filter: "alpha(opacity=100)"});
    131. animating = false;
    132. });
    133. }
    134. }
    135. });
    136. }
    137. });

    效果預覽~~

    在線代碼調試:地址

     原文鏈接:http://www.gbtags.com/gb/share/5781.htm

    相似問題

    相關經驗

    相關資訊

    相關文檔

  • sesese色