虽然现如今 <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
逻辑:极其简单
我好像发现了什么不得了的东西(表情
最后我们用 Vue 来做个演示:
0
【相关资料】
0、Jurgen Leckie – Tables◃flickr