合并单元格与数据列表

tables

虽然现如今 <table> 已经逐渐远离前端的视线,
但在大量数据项整齐排列的场合,它还是必要的存在。
去年有提过如何在表格行间插入可控制显示的内容的方法,
这次就来说说有关合并单元格(rowspan/colspan)的事情。

当数据与前端结构/样式分离后,页面不再是完全“静态”的。
特别是列表型数据,我们就无法准确得知最终插入元素的数量。
如果插入的是 <ol>/<ul> 还好,
<table><tr> 逐行显示也没什么问题。
但是如果需要在表格用合并单元格进行跨行(列)处理,就会遇到麻烦了。

0

随手举个机场快线的例子,
一趟班车的线路可能有多个(当然这个例子里只有两个或零个)。
我们需要通过 rowspan 让左侧父级数据占据足够的行数。
而子级的数据则放在父级右侧以及跟随的行中。
父级加第一组子级数据所在的行,与其它子级所在的行,构造完全不同。

数据分离出来非常简单,两条正常线路和一条停运线路(子级数据为空):

var express = [{
  no: 'Airport Express Line 2',
  dest: 'Shenzhen airport - Luohu Railway Station',
  lines: [{
    dir: 'To Luohu Railway Station',
    time: '07:45 - 24:00'
  },{
    dir: 'To Shenzhen airport',
    time: '06:30 - 22:00'
  }]
},{
  no: 'Airport Express Line 3',
  dest: 'Shenzhen airport - Longgang Jiadebao',
  lines: [{
    dir: 'To Longgang Jiadebao',
    time: '08:00 - 22:00'
  },{
    dir: 'To Shenzhen airport',
    time: '06:20 - 20:30'
  }]
},{
  no: 'Airport Express Line 4',
  dest: 'Shenzhen airport - longgang pinghu South City',
  lines: []
}];

所谓“健壮性”,当然是期望仅仅设计一套模版,任何数据都能得到良好的展示。
而对于非常规数据进行的额外修正越少,逻辑越简单,则越“优雅”。
回到我们的问题,仔细分析:

1、父级数据的跨行数,显然是与子级数据的个数相同的
但当子级数据为空时,则会得到 rowspan=0
根据 HTML4 规范,这代表着该行会跨越整个表格,
而这显然与我们多个父级数据的需求相违背。
何况该属性在各个浏览器上表现不尽相同
我大 chrome 干脆不理会它,当作默认的 rowspan=1
firefox 倒是挺老实地实现了,而 opera 处理了跨行,而放弃了跨列(colspan=0)。
所以我们需要一个额外修正:
当子级数据为空时,父级数据跨行数为 1。

2、子级数据并不完全是跟随父级数据逐行显示
这就至少需要增加两个个额外修正:
a)不跟随显示其首个数据,而与父级同行显示。
b)子级数据为空则父级对应位置为一个空白单元格,而非完全不显示。

因此我们的确可以按此设计出一套模版,但同时也必须进行复杂的修正。
各种问题的核心,最最麻烦的地方,就是父级数据与首个子级数据这一行。
它不但割裂了子级数据的完整性,同时也破坏了数据层级之间的独立性。
但这是无法避免的历史遗留问题,表单出现和统治互联网的时代里,
网页上的数据、结构、样式还是混杂的,不像今天这般泾渭分明。

所幸,这并不是唯一的解决方法。

到目前为止,我们做的都是“修正”——
维持与静态布局一致,哪里不合适就修改哪里。
既然之前的方式虽然保证了样式,但会有损数据的完整性与独立性。
如果换一个思路会怎么样呢?保证数据而不拘泥于样式。
最简单的想法当然是类似列表而不是跨行表格,
首行父级数据,跟随多行子级数据,没有就不显示,如此反复即可。

<ul>
  <li>
    <div class="parent">
      <span>Airport Express Line 2</span>
      <span>Shenzhen airport - Luohu Railway Station</span>
    </div>
    <ul class="child">
      <li>
        <div>To Luohu Railway Station</div>
        <div>07:45 - 24:00</div>
      </li>
      <li>
        <div>To Shenzhen airport</div>
        <div>06:30 - 22:00</div>
      </li>
    <ul>
  </li>
</ul>

如果把这种模式带到表格中,
难道首行只显示父级数据?不管子级数据了?空着?
子级数据为零,就是应该空着啊,咦?!
子级有数据时候嫌空着不好看……那,我们把它隐藏起来?可以嘛?
但是这样一来首行跨行数就是子级数量 +1 了,
那么当子级数为零时,就自动是完美无瑕的 rowspan=1,唉?!

问题:解决
修正:1
逻辑:极其简单

我好像发现了什么不得了的东西(表情
最后我们用 来做个演示:

0

【相关资料】
0、Jurgen Leckie – Tables◃flickr

发表评论

邮箱地址不会被公开。 必填项已用*标注