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、总结

至此本文就结束了,关于冻结列的课题终于能够暂时告一段落了,这个问题博主纠结了好久,总算是解决了。若是你以为本文可以帮助你,能够右边随意 打赏 博主,打赏后能够得到博主永久免费的技术支持。

相关文章
相关标签/搜索