1. 程式人生 > >東拼西湊完成一個“前端框架”(5) - Tabs操作

東拼西湊完成一個“前端框架”(5) - Tabs操作

目錄

  • 東拼西湊完成一個後臺 ”前端框架“ (1) - 佈局
  • 東拼西湊完成一個後臺 ”前端框架“ (2) - 字型圖示
  • 東拼西湊完成一個“前端框架”(3) - 側邊欄
  • 東拼西湊完成一個“前端框架”(4) - Tabs頁

寫在前面

Tabs頁面完成的基本操作完成,但是功能還不夠完備:

  • Tab頁開啟過多超出的如何處理?
  • Tab頁關閉所有、關閉其它操作
  • Tab頁重新整理操作

設計

這裡參考LayUIAdmin的設計方式:

  1. Tab欄左右未知可以動態調整
  2. 開啟的標籤頁面超出時,調整位置到指定標籤頁顯示
  3. 左右滑動不同範圍的標籤頁

佈局

  • Tab欄左右位置可以調整,那麼Tab欄的定位是絕對定位
  • 左右調整動畫 transaction

程式碼

HTML

···
 <div class="ls-tab-container">
    <div class="header flex">
        <!--left-->
        <div class="tab-operate tab-operate-left">
            <a class="fa fa-2x fa-angle-double-left opt-left"></a>
        </div>
        <!--titles-->
        <div class="ls-tab-titles flex">
            <div class="tab-title active" data-id="0">
                <span class="title">
                    <i class="ls-icon ls-icon-home"></i>
                </span>
            </div>
        </div>
        <!--right-->
        <div class="tab-operate tab-operate-right">
            <a class="fa fa-2x fa-angle-double-right opt-right"></a>
            <a class="fa fa-2x fa-angle-double-down">
                <div class="dropdown-panel">
                    <ul>
                        <li class="opt" data-opt="refresh">重新整理</li>
                        <li class="opt" data-opt="closeOthers">關閉其它</li>
                        <li class="opt" data-opt="closeAll">全部關閉</li>
                    </ul>
                </div>
            </a>
        </div>
    </div>
···
</div>
···

CSS

<!--Tabs欄-->
.ls-tab-container .ls-tab-titles {
    position: absolute;
    left: 39px;
    right: 78px;
    overflow: hidden;
    transition: all 300ms ease-in;
    -webkit-transition: all 300ms ease-in;
}
<!--操作-->

.tab-operate {
    position: absolute;
    display: flex;
    text-align: center;
    border-bottom: 1px solid #e6e6e6;
    background: rgba(255, 255, 255, 1);
    box-shadow: 0 0 6px rgba(196, 199, 202, 0.35);
    z-index: 8;
}

.tab-operate .fa:hover {
    background: rgba(238, 238, 238, .6);
    cursor: pointer;
}

.tab-operate.tab-operate-left {
    left: 0;
}

.tab-operate.tab-operate-right {
    right: 0;
}

.tab-operate .fa {
    color: #666;
    font-size: 22px;
    line-height: 36px;
    width: 38px;
    display: inline-block;
}

.tab-operate-left .fa {
    border-right: 1px solid rgb(230, 230, 230, .8);
}

.tab-operate-right .fa {
    border-left: 1px solid rgb(230, 230, 230, .8);
    position: relative;
}

效果

下拉選單

滑鼠經過最右側操作按鈕時展示下拉選單,思路很簡單就算用偽類 hover 實現,但是在利用transaction做動畫的過程中發現,display 屬性與 transaction 屬性衝突,解決方式是通過 height:0;overflow:hidden; 來實現動畫:

.dropdown-panel {
    background: #fff;
    position: absolute;
    width: 120px;
    right: 0;
    font-size: 13px;
    transition: top 200ms ease-in, opacity 200ms ease-in;
    -webkit-transition: top 200ms ease-in, opacity 200ms ease-in;
    border-radius: 4px;
    top: 46px;
    height: 0;
    opacity: 0;
    overflow: hidden;
    box-shadow: 0 0 6px rgba(196, 199, 202, .35);
}

.tab-operate-right .fa:hover .dropdown-panel {
    top: 37px;
    opacity: 1;
    height: auto;
    border: 1px solid rgb(230, 230, 230, .8);
}

效果預覽

操作

思路


如圖所示 開啟多個標籤頁時只要把超出的部分利用 Tab欄margin-left 屬性補回來就可以實現:
margin-left: (Tab欄.Offset().Left+Tabs欄.Width() - TabItem.Offset().Left-TabItem.Width()) + 'px'

關鍵程式碼實現

// 啟用Tab時觸發
···
// 位置調整
var pleft = $tab.offset().left + 39;
var pright = $tab.offset().left + $tab.width() - 80;
var cleft = $tabTitle.offset().left;
var cright = cleft + $tabTitle.width() + 30;
var cmgLeft = parseFloat($tabTitle.parent().css("margin-left").replace("px", ""));

if (cleft < pleft) {
    cmgLeft = (cmgLeft + pleft - cleft);
    $tabTitle.parent().css("margin-left", cmgLeft + "px");
} else if (cright > pright) {
    cmgLeft = (cmgLeft + pright - cright);
    $tabTitle.parent().css("margin-left", cmgLeft + "px");
}
···

左右滑動

思路

分頁的思想:把Tabs欄的寬度類比為 PageSize[分頁大小] , 開啟標籤頁佔用的總長度類比為 TotalCount[總數]

關鍵程式碼實現


/**
 * 翻頁
 * @param {頁碼}} pageIndex 
 */
var changePage = function(diff) {
    // 容器寬度
    var cWidth = $('.ls-tab-container').width() - 119;
    var $firstTitle = $('.ls-tab-titles .tab-title:first'),
        $lastTitle = $('.ls-tab-titles .tab-title:last');
    // 內容寬度
    var tsWidth = $lastTitle.offset().left -
        $firstTitle.offset().left +
        $lastTitle.width() + 30;
    var curPage = $title_container.attr("cur-p");

    // 容器 margin-left 用於計算當前頁碼
    var cmgLeft = parseFloat($title_container.css("margin-left").replace("px", ""));
    curPage = Math.floor(Math.abs(cmgLeft) / cWidth) + 1;

    var totalPage = Math.floor(tsWidth / cWidth) + (tsWidth % cWidth > 0 ? 1 : 0);
    curPage = curPage + diff;
    if (curPage >= totalPage) {
        curPage = totalPage;
        $title_container
            .css("margin-left", (1 - totalPage) * cWidth + "px")
            .attr("cur-p", totalPage);
    } else if (curPage <= 1) {
        curPage = 1;
        $title_container
            .css("margin-left", "0px")
            .attr("cur-p", "1");
    } else {
        $title_container
            .css("margin-left", (1 - curPage) * cWidth + "px")
            .attr("cur-p", curPage);
    }
}

效果預覽

歡迎批評指正

原始碼地址

https://github.com/LaosanShang/ls-admin-front