JS組件系列——本身動手擴展BootstrapTable的 凍結列 功能:完全解決高度問題

 

正文css

前言:一年前,博主分享過一篇關於bootstrapTable組件凍結列的解決方案  JS組件系列——Bootstrap Table 凍結列功能IE瀏覽器兼容性問題解決方案 ,經過該篇,確實能夠實現bootstrapTable的凍結列效果,而且能夠兼容ie瀏覽器。這一年的時間,不斷有園友以及羣裏面的朋友問過我關於固定高度以後,凍結列頁面效果不能對齊的問題,奈何博主太忙,一直沒有抽空將這個問題優化。最近項目裏面也不斷有人提過這個bug,這下子不能再推了,必需要直面「慘淡的bug」,因而昨天利用一天的時間將原來的擴展作了一下修改,可以完美解決固定高度以後凍結列的問題,而且,博主還加了一些特性,好比右側列的凍結、凍結列的選中等等,有須要的朋友能夠捧個場。相信經過此篇,老闆不再用擔憂個人凍結列不能固定高度了~~html

本文原創地址:http://www.cnblogs.com/landeanfen/p/7095414.htmljava

1、問題追蹤

記得在以前的那篇裏面介紹過,bootstrapTable組件自帶的凍結列擴展,不能兼容ie瀏覽器,即便最新版本的ie也會沒法使用,這是通常的系統不能忍受的,因此在那篇裏面給出過解決方案,但並未分析ie瀏覽器不能兼容的緣由,昨天博主花了點時間特地調試了下源碼,原來在ie裏面,使用jquery的clone()方法和谷歌等瀏覽器有所區別。爲了展現這個區別,這裏先拋個磚。好比有以下代碼:jquery

複製代碼
<table id="tbtest">
    <tr><td>aaa</td><td>bbb</td><td>ccc</td></tr>
    <tr><td>ddd</td><td>eee</td><td>fff</td></tr>
    <tr><td>ggg</td><td>hhh</td><td>iii</td></tr>
</table>

<script type="text/javascript">
    var $tr = $('#tbtest tr:eq(0)').clone();
    var $tds = $tr.find('td');

    $tr.html('');

    alert($tds.eq(0).html());
</script>
複製代碼

代碼自己很簡單,只是爲了測試用。看到這裏你能夠試着猜一下alert的結果。bootstrap

算了,不考你們了,直接貼出來吧,有圖有真相!瀏覽器

相信不用我過多的解釋哪一個是ie,哪一個是谷歌了吧。app

二者的區別很明顯,谷歌裏面獲得「aaa」,而ie裏面獲得空字符串。這是爲何呢?post

其實若是你用值類型和引用類型的區別來解釋這個差異你就不難理解了,在谷歌瀏覽器裏面,$tr變量是一個引用類型,當你清空了它裏面的內容,只是清除了$tr這個變量的「指針」,或者叫指向,$tds變量仍然指向了$tr的原始內容,因此調用$tds.eq(0).html()的時候仍然能獲得結果aaa;一樣的代碼在ie瀏覽器裏面,$tr變量就是一個值類型,你清空了它裏面的內容以後,$tds的內容也被清空了。若是你有更好的解釋,歡迎賜教哈。性能

之因此組件原生的js不能兼容ie瀏覽器,就是由於它使用了clone()這個方法,致使在不一樣的瀏覽器看到不一樣的結果。相信bootstrapTable組件的做者應該是知道這個區別的,只不過沒有太在乎這些,從做者作的不少功能的兼容性可以看出,他作的功能不少沒有太多的考慮ie瀏覽器的效果。

2、效果預覽

仍是老規矩,說了這個多,沒圖怎麼行,小二,上圖!

沒有固定高度的狀況:單列凍結。

 

多列凍結。

 固定任意高度效果 

 

ie瀏覽器也沒有問題,這裏就再也不重複上圖了。

3、源碼解析

源碼沒啥說的,有興趣能夠本身看看,主要的原理仍是重寫bootstrapTable構造器的事件,來達到想要的效果。

  bootstrap-table-fixed-columns.js
  bootstrap-table-fixed-columns.css

如何使用呢?這裏博主單獨搞了一個靜態的html測試頁,仍是貼出來供你們參考。

  bootstrapTableFixColumns.html

 代碼釋疑:

一、源碼各個方法解釋

  • BootstrapTable.prototype.initFixedColumns :當初始化的時候配置了fixedColumns: true時須要執行的凍結列的方法。
  • BootstrapTable.prototype.initHeader:重寫組件的的初始化表頭的方法,加入凍結的表頭。
  • BootstrapTable.prototype.initBody:重寫組件的初始化表內容的方法,加入凍結的表內容。
  •  BootstrapTable.prototype.resetView:重寫「父類」的resetView方法,經過setTimeout去設置凍結的表頭和表體的寬度和高度。
  • BootstrapTable.prototype.fitHeaderColumns:設置凍結列的表頭的寬高。
  • BootstrapTable.prototype.fitBodyColumns :設置凍結列的表體的寬高,以及滾動條和主體表格的滾動條同步。

 二、對於上述拋出的ie和谷歌的兼容性問題的解析

查看BootstrapTable.prototype.initBody方法,你會發現裏面寫有部分註釋。

複製代碼
this.$body.find('> tr[data-index]').each(function () {
            var $tr = $(this).clone(),
                $tds = $tr.find('td');

            //$tr.html('');這樣存在一個兼容性問題,在IE瀏覽器裏面,清空tr,$tds的值也會被清空。
            //$tr.html('');
            var $newtr = $('<tr></tr>');
            $newtr.attr('data-index', $tr.attr('data-index'));
            $newtr.attr('data-uniqueid', $tr.attr('data-uniqueid'));
            var end = that.options.fixedNumber;
            if (rowspan > 0) {
                --end;
                --rowspan;
            }
            for (var i = 0; i < end; i++) {
                $newtr.append($tds.eq(i).clone());
            }
            that.$fixedBodyColumns.append($newtr);

            if ($tds.eq(0).attr('rowspan')) {
                rowspan = $tds.eq(0).attr('rowspan') - 1;
            }
        });
複製代碼

這一段作了部分修改,有興趣能夠調適細看。

三、項目中的使用

 最近在研究學習abp的相關源碼,將bootstrapTable融入abp裏面去了,貼出表格凍結的一些效果圖。

 

四、擴展

除此以外,還特地作了右邊操做列的凍結。

和左邊列的凍結同樣,最右邊列的凍結也是能夠作的,最不一樣的地方莫過於右邊列有一些操做按鈕,若是在點擊凍結列上面的按鈕時觸發實際表格的按鈕事件是難點。若是有這個需求,能夠看看。

  bootstrap-table-fixed-columns.js
  bootstrap-table-fixed-columns.css

須要說明的是,因爲時間問題,右側固定列的代碼和上述解決高度的代碼並未合併,因此若是你既想要解決凍結列的高度,又想要右側列的凍結,須要本身花點時間合併下代碼。

4、總結

至此本文就結束了,關於凍結列的課題終於能夠暫時告一段落了,這個問題博主糾結了好久,總算是解決了。若是你以爲本文可以幫助你,能夠右邊隨意 打賞 博主,打賞後能夠得到博主永久免費的技術支持。

相關文章
相關標籤/搜索