SlickGrid 样式在 JQueryUI Accordion 和 Bootstrap框架的兼容性解决办法

文章详细记录了SlickGrid在jQueryAccordion和Bootstrap3中遇到的两个复杂问题:Accordion中格式不一致的问题和在IE8中网格内容消失的问题,并提供了解决方案。此外,还解释了Bootstrap3中列宽问题的原因及解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SlickGrid with jQueryUI and Bootstrap


原文地址:http://low-bandwidth.blogspot.com.au/2015/06/slickgrid-with-jqueryui-and-bootstrap.html

Recently I've taken up the mantle of maintaining an updated fork of MLeibman's fantastic SlickGrid trunk. I suppose it was inevitable that it would lead to a blog post.

There have been multiple issues posted about the jQuery Accordion and about Bootstrap 3 issues with sizing. After examination, the bootstrap issue is quite complex and I thought it was worth documenting the details of both.
The first step was to add stripped down, simple example pages for both cases to be used for testing.  example-jquery-accordion.html and example-bootstrap-3-header.html are now present in the examples folder of my  alternative master repository.

Accordion Formatting

The formatting of the SlickGrid header row was showing small inconsistencies in header size:








This was a minor CSS issue: it appears that in normal situations the header is formatted by the 
.slick-header-column.ui-state-default class, which is being evaluated as more specific than (hence takes precedence over) the generic jQueryUI ui-state-default class.
When enclosed in the accordion div (and I'd assume tabs or any other similar container),  ui-state-default gets precedence and adds extra border segments.
It is easily fixed by adding the  !important tag to various SlickGrid header classes. This is exactly the kind of situation that  !important is designed for.

.slick-header.ui-state-default, .slick-headerrow.ui-state-default {
  width: 100%;
  overflow: hidden;
  border-left: 0px !important;
}
.slick-header-column.ui-state-default {
  position: relative;
  display: inline-block;
  overflow: hidden;
  -o-text-overflow: ellipsis;
  text-overflow: ellipsis;
  height: 16px;
  line-height: 16px;
  margin: 0;
  padding: 4px;
  border-right: 1px solid silver;
  border-left: 0px !important;
  border-top: 0px !important;
  border-bottom: 0px !important;
  float: left;
}

Blank Grid Display in Accordion in IE8

More sinister was a problem with vanishing grid contents. I tested in IE8 but other IE versions may also be implicated.
Steps to reproduce using the accordion demo page:
1) open the page in IE 8 and scroll the first grid down a page or so.
2) switch to the second accordion, then back
The first grid should now be blank.

This is an IE rendering issue - IE resets the scrollbar and display when a div or its parent is hidden with  display:none. Checking it out with the IE developer tools showed that the DOM elements still existed, but just weren't being shown. Probably because of this, all attempts to refresh the grid failed. Only destroying and recreating the grid was able to get past the blank display.

Because this workaround changes the screen UI, I have commented the code out in the demo page, but it is there if needed.
I was unable (and frankly unwilling) to find a solution for what appears to be an IE bug. If anyone finds a mechanism for refreshing the blank div, let me know and I'll bake it in to the grid.

Bootstrap 3 Column Width Issues

There have been many reports of column width issues under Bootstrap 3. It doesn't take long to find the culprit. Simply including the bootstrap.css file on your page includes this little gem:

* {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}
*:before,
*:after {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}

Admittedly, border-box is a much more sensible model, but this css forces  border-box onto most elements on the page (some inputs are excluded).
The interesting thing is that the main (MLeibman) branch of SlickGrid, which is at jQuery 1.7, deals with this perfectly. The header height needs css tweaking, but the column widths resize and drag fine. It's only after we update jQuery that the trouble starts.

The problem is similar to the first image, but it only starts when resizing columns. The drag handle and column header size are offset by an amount equal to the padding and border widths of the column. Worse, the effect is cumulative each time the column is resized.

The reason is summarised  here (thanks to  JCReady for the heads up). The way jQuery handles  box-sizing: border-box in relation to the .width and .outerWidth properties changed in jQuery 1.8. Before, .width essentially did a .css("width") which meant that it would return different numbers depending on the  box-sizing setting. Afterwards, it returned the correct inner element size regardless of the  box-sizing setting (note that it warns of the performance hit for this feature).
1.8 also allowed .outerWidth to be used as a setter.

Solution 1

A very easy (and tempting) solution is to follow in the footsteps of the css fixes above and add:

slick-header-column.ui-state-default {
   box-sizing: content-box !important;
}

This works just fine since the existing codebase was written to use the default  box-sizing: content-box setting. However, it is conceivable that border-box could be needed on the header elements, particularly when using the menu and button features that are available. I resolved to rather solve the problem in the code.

Solution 2

Most of the forum fixes for the column sizing issue recommend replacing all occurences of  .width with  .outerWidth. This works for the   box-sizing: border-box case but manifests a mirror image problem with  content-box (ie. the offset is negative instead of positive).
In order to preserve the correct operation under the old and new jQuery versions in both   box-sizing cases, it was necessary to sniff the jQuery version and provide an alternate code path.
In the end, it was only necessary to make a small adjustment to  applyColumnHeaderWidths to solve the issue.
See the  commit for code details.
6 comments:
  1. Youre the man! Will keep you updated on if the change works. Thank you

    ReplyDelete
  2. Thanks! I have been testing on Chrome and IE8, but testing on a bigger range of browsers would be a bonus.

    ReplyDelete
  3. Hello Ben. Great Work. in "slick.grid.js" file, around line 925 where you are checking new jQuery behavior, you only check if major is >=1 and minor >=8, so it will not work if minor release is less than 8, but major release is more than 1, i.e. 2.1.1 etc.

    For my code, I added the 3rd line below:
    var verArray = $.fn.jquery.split('.');
    jQueryNewWidthBehaviour = verArray[0]>=1 && verArray[1]>=8;
    jQueryNewWidthBehavior = verArray[0] >=2 ; //if jquery version is 2 or more , its automatically greater than 1 :)

    ReplyDelete
  4. good catch. however, I think your new code line code overwrites the value from the previous line!
    you should use |=, or use an or || clause to join it to the first line.
    anyway, I'll patch the repo right now.

    ReplyDelete
  5. jQueryNewWidthBehaviour = (verArray[0]==1 && verArray[1]>=8) || verArray[0] >=2;

    ReplyDelete

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值