固定表頭/鎖定前幾列的代碼參考[JS篇]


  引語:做有難度的事情,才是成長最快的時候。前段時間,接了一個公司的稍微大點的項目,急着趕進度,本人又沒有獨立帶過隊,因此,把自己給搞懵逼了。總是沒有多余的時間來做自己想做的事,而且,經常把工作帶入生活,這TM真是一個糟糕的事情!這兩天,終於把項目上上去了,不管結果怎么樣,總算是交差了吧。趁着這空檔的時間,寫點東西。

  本篇,就來寫寫關於固定表頭和表列的事兒吧。

  相信大家使用excel的時候,肯定都會用到一項凍結的功能,凍結之后,可以讓你很方便的查看到各種標題,從而能清楚的查看到當前行的內容。

  這個凍結鎖定的需求,來源於頁面太長,太寬。

  那么,對於網頁版本的凍結鎖定,是不是也有相應的功能呢?去網上搜索插件,基本上又都只是固定表頭的,並不能固定前幾列。不過幸好,不知道從哪里撿到一部分代碼,改了一下內部代碼,匆忙將功能實現,進入下一步。下面就跟大家分享一下,鎖定表頭、前幾列的這段代碼,也可以認為是個小插件,希望在你需要時,能幫上點忙!(實在沒有找到作者是誰,如果你知道,請告知我,我一定加上作者姓名)

  獨立源碼如下:

(function($) {
    $.fn.magicTable = function(option) {
        $.fn.magicTable.option = {
            /* 浮動頭部 */
            'magicTop': $('#J_MagicTableTop'),
            'magicLeft': $('#J_MagicTableLeft'),
            /* 可能有隱藏的,所以設定浮動頭部的開始索引 */
            'leftIndex': 0,
            'leftFlg': false,
            /* 高度調整 */
            "thfix": 0,
            "thWidth": 0, //左邊顯示的寬度
            "thHeight": 0,
            "thTop": 0,
            "thLeft":0,
            "thLine": 0,
            "removeTotal": false
        };
        var option = $.extend({}, $.fn.magicTable.option, option);
        
        return this.each(function() {
            $(this).css({'z-index': '9', 'display': '', 'position': 'relative'});

            /*復制活動的表格內容*/
            var leftHtml = '';
            var leftHtml2 = '';
            var leftFlg = option.leftFlg;
            var thWidth = option.thWidth;
            var thHeight = 0; //th的高度
            var thTop = option.thTop; //th距離瀏覽器頂部的top高度
            var thLeft = option.thLeft; //左側未滾動時的left
            var removeTotal = option.removeTotal;//除去最后一行的匯總
            var flagLeftLength = 0; //左側顯示浮動層時的臨界點
            
            //處理浮動的頭部
            option.magicTop.html($(this).find('thead').clone()).css({
                'width': $(this).width()
            });

            var trLenght = $(this).find('>tbody>tr').length;
            if(removeTotal)
            {
                trLenght -= 1;
            }

            $(this).find('tr').each(function(i, item) {
                var maxHeight = $(this).height();
                $(this).find('td').each(function(tdI, tdItem){
                    var height = $(this).height();
                    if(height > maxHeight){
                        maxHeight = height;
                    }
                });
                if (i == option.thLine){
                    thTop = thTop > 0 ? thTop : $(this).find('th:first').offset().top;
                    thHeight = $(this).height();  //包圍th的tr的高度
                    thLeft = $(this).offset().left; //表格左側是的left
                    flagLeftLength = $(this).find('th:eq(' + option.leftIndex + ')').offset().left; 
                    thWidth = flagLeftLength + $(this).find('th:eq(' + option.leftIndex + ')').outerWidth() - thLeft;
                } else if (i > option.thLine) {
                    if (leftFlg && (i <= trLenght)){
                        var tmpHtml = '';
                        for (var j = 0; j <= option.leftIndex; j++) {
                            tmpHtml += '<td style="height:' + maxHeight + 'px;width:' +
                                    $(this).find('td:eq(' + j + ')').innerWidth() + 'px">' + $(this).find('td:eq(' + j + ')').html() + '</td>';
                        }
                        leftHtml2 += '<tr>' + tmpHtml + '</tr>';
                    }
                    leftHtml = leftHtml + '<tr><td style="height:' + maxHeight + 'px">' +
                            $(this).find('td:eq(' + option.leftIndex + ')').html() + '</td><tr>';     
                }
            });

            if (leftFlg) {
                leftHtml = leftHtml2;
                option.magicLeft.html(leftHtml);
            }

            /*活動模塊*/
            function moveSquare(){
                if ($(this).scrollTop() >= thTop){
                    option.magicTop.show().css({'z-index': '999', 'position': 'absolute', 'top': $(this).scrollTop() + option.thfix + 'px'});
                } else {
                    option.magicTop.css({'display': 'none'});
                }
                
                if ($(this).scrollLeft() >= thLeft) {
                    option.magicLeft.show().css({
                        'z-index': '99', 
                        'position': 'absolute', 
                        'top': thTop + thHeight - 1 + 'px',
                        'left': $(this).scrollLeft() - 1 + 'px',
                        'width': thWidth + 'px',
                    });
                    if ($(this).scrollTop() >= thTop){
                        option.magicLeft.show().css({
                            'top': thTop + thHeight - option.thfix - 1 + 'px'
                        });
                    }
                } else {
                    option.magicLeft.css({'display': 'none'});
                }
            }
            
            if (document.all) {
                window.attachEvent("onscroll", moveSquare);
            } else {
                window.addEventListener('scroll', moveSquare, false);
            }

        });
    };

    $.fn.magicTable.setDefaults = function(settings) {
        $.extend($.fn.magicTable.option, settings);
    };
})(jQuery);

  使用方法:

    1. 在表格之前,添加一個空的表格頭table,在表格之后,添加一個空的表格列table,示例如下:

     <table id="J_MagicTableTop" class="table table-bordered data-list" style="display:none;"></table>
           <table class="table table-bordered data-list" id="J_MagicTable">
                    <thead>
                    <tr>
                        <th style="width:80px;">產品</th>
                        <th style="width:110px;">任務名稱</th>
                        <th>操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    </tbody>
           </table>
      <table id="J_MagicTableLeft" class="table table-bordered data-list magic-table-left" style="display:none;"></table>

    2. 添加js綁定事件

        if ($("#J_MagicTable").length > 0) {
            var blockHeadingHeight = $("#J_BlockHeading").outerHeight();    //用於設置最上面的間隙
            $('#J_MagicTable').magicTable({thfix: blockHeadingHeight, leftIndex: 2, leftFlg: true});
        }    

  就這樣就可以實現,固定表頭和前3列的效果了,還是很不錯的。

  但是需要注意以下幾點:

    1. 表結構一定是table > thead > th 這種結構的,表頭中一定是有th這個元素的;

    2. 表頭一定要加上width寬度指示,否則將出現嚴重錯位;

    3. 即使是使用了width指示,也會出現錯位情況,應該讓table>tr>td 設置文字打斷, word-break: break-all;

    4. 盡量不要使用colspan屬性;

 

  原理解析:

    其實也很簡單,就是利用了一個position: absolute; 起到絕對定位的作用,通過檢測當前所處位置,改變他的位置。表頭、表列為復制的原表格的屬性,不必單獨填寫;

  有待改進的地方:

    我本人已經作了部分修改,但是鑒於時間關系,沒有細改。待完善: 1. 不用指定表頭及表列所在的空位,自行創建即可;2. 獲取真實td,th的寬度,不必要全部計算設置;

 

  OK,以上為今天的分享,如果有什么不對的地方,歡迎批評指正。如果你有什么疑問,也可以直接@我,我會盡快回復的!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM