Recently my article on creating elegant table data with OpenType gained some attention via a much-appreciated tweet from Smashing Magazine. In response to that, a commenter quite correctly pointed out that the table was not responsive: as the browser window narrowed, data was cut off.
最近,我有关使用OpenType创建优雅的表数据的文章通过Smashing Magazine广受赞赏的推文获得了一些关注。 对此,评论者非常正确地指出该表没有响应 :随着浏览器窗口范围的缩小,数据被切断。
I couldn’t change the table as I have in previous examples: the order and direction of the data matters, and must be retained. However, there is another possible solution.
我无法像以前的示例一样更改表:数据的顺序和方向很重要,必须保留。 但是,还有另一种可能的解决方案。
Microsoft Excel and other spreadsheet applications have a feature called “pivot tables”, which translate rows into columns. For certain kinds of tables, such as the one shown at the top of this article, the same effect can be achieved on web pages using JavaScript.
Microsoft Excel和其他电子表格应用程序具有一项称为“数据透视表”的功能,该功能可将行转换为列。 对于某些类型的表,例如本文顶部显示的表,可以使用JavaScript在网页上实现相同的效果。
从标记开始 (Starting with Markup)
The table starts with similar markup to the OpenType example, but accessorized with an id
and class
(optional closing tags have been removed to simplify and clarify the code).
该表以与OpenType示例类似的标记开头,但以id
和class
进行了装饰(已删除可选的结束标记以简化和阐明代码)。
<table id="gg" class="large">
<caption>2014 Greenhouse gas emissions, per country</caption>
<thead>
<tr>
<td>
<th scope="col">China
<th scope="col"><abbr title="United States of America">USA</abbr>
<th scope="col"><abbr title="European Union">EU</abbr>
<th scope="col">India
<th scope="col">Russia
</thead>
<tbody>
<tr>
<th scope="row">CO<sub>2</sub> (mt)
<td>10,540
<td>5,334
<td>3,415
<td>2,341
<td>1,766
<tr>
<th scope="row">Emission per capita (t)
<td>7.6
<td>16.5
<td>6.7
<td>1.8
<td>12.4
</tbody>
</table>
The CSS is similar too. I’ve written this example in Sass:
table {
margin: 2rem auto;
font-size: 1.6rem;
border-collapse: collapse;
@media all and (max-width: 636px) {
font-size: 1.4rem;
}
@media all and (max-width: 522px) {
font-size: 1.2rem;
}
table td {
text-align: right;
padding: .5rem;
width: 5rem;
}
table thead th {
border-bottom: 1px solid #777;
font-weight: 400;
}
table tbody th {
font-weight: 400;
text-align: right;
padding-right: 1rem;
}
table caption {
font-weight: 600;
margin-bottom: 1rem;
}
table tbody td {
color: #444;
}
透视 (Pivotting)
The current table structure is read JavaScript as a variable called fulltable
; without JavaScript, the table will still be shown; it just won’t pivot.
当前的表结构被JavaScript读取为称为fulltable
的变量 ; 如果没有JavaScript,表格仍会显示; 它只是不会旋转。
var fullTable = document.querySelector(".large").innerHTML,
caption = gg.getElementsByTagName("caption"),
ggHead = gg.querySelector("thead tr"),
ggBody = gg.querySelector("tbody"),
ggColHeaders = ggHead.querySelectorAll("th"),
ggDataHeaders = ggBody.querySelectorAll("tr th"),
ggDataRows = ggBody.querySelectorAll("tr"),
matchPoint = window.matchMedia("(max-width: 600px)"),
slimTable;
Each variable contains a part of the table.
每个变量都包含表的一部分。
function pivotTable() {
if (matchPoint.matches && gg.matches(".large")) {
if (typeof slimTable === 'undefined') {
ggHead.innerHTML = "<td> </td>";
for (var i = 0; i < ggDataHeaders.length; i++) {
var scoped = ggDataHeaders[i];
scoped.scope = "col";
ggHead.appendChild(scoped);
}
var totalCols = ggDataRows[0].getElementsByTagName("td").length;
ggBody.innerHTML = "";
for (var j = 0; j < totalCols; j++) {
var newRow = document.createElement("tr");
var newRowHeader = document.createElement("th");
newRowHeader.scope = "row";
newRowHeader.innerHTML = ggColHeaders[j].innerText;
newRow.appendChild(newRowHeader);
for (var k = 0; k < ggDataRows.length; k++) {
var currentRowData = ggDataRows[k].getElementsByTagName("td");
var newCell = document.createElement("td");
newCell.innerHTML = currentRowData[j].innerText;
newRow.appendChild(newCell);
}
ggBody.appendChild(newRow);
}
} else {
gg.innerHTML = slimTable;
}
gg.classList.remove("large");
gg.classList.add("small");
slimTable = document.querySelector(".small").innerHTML;
}
if (gg.matches(".small") && !matchPoint.matches) {
console.log("Upsize");
gg.innerHTML = fullTable;
gg.classList.remove("small");
gg.classList.add("large");
}
}
The pivotTable
function swaps rows into columns, placing the header cells that were originally on the left of each row at the top of each column. Semantically (and from an accessibility perspective) the data remains the same, just presented in a different view.
的pivotTable
功能互换行转换成列,布置一个最初每行的左侧在每一列的顶部的标题细胞。 从语义上(从可访问性的角度来看),数据保持不变,只是以不同的视图显示。
When the data is pivoted, the table class
is switched from large
to small
; the pivoted version of the table structure is recorded into the slimTable
vaaible so that the pivot process doesn’t have to repeat itself if the viewport is made large and small again.
当数据旋转时,表class
从large
切换到small
; 表格结构的枢轴版本记录在slimTable
变量中,这样,如果视口再次变大或变小,枢轴过程就不必重复。
The pivotTable
function is called once on page load:
pivotTable
加载页面时, pivotTable
函数都会调用一次:
pivotTable();
We don’t want to have to check if we need to call the pivotTable
function every time the browser viewport is resized - that would drag down performance of the page - so I’ve throttled it to check every 200 milliseconds during a resize
event:
我们不需要每次调整浏览器视口大小时是否都需要检查是否需要调用pivotTable
函数-这会降低页面的性能-因此,我限制了它在resize
事件期间每200毫秒检查一次:
window.addEventListener("resize", throttle( pivotTable, 200 ));
That throttle process is a function in itself:
节流过程本身就是一个功能:
function throttle (callback, limit) {
var wait = false;
return function () {
if (!wait) {
callback.call();
wait = true;
setTimeout(function () {
wait = false;
}, limit);
}
}
}
结论 (Conclusion)
While not suitable for every table - those with just as many rows as there are columns would be an unsuitable candidate for this technique - but it could be very useful for tables like those above.
虽然不适合每个表-行数与列数一样多的表不适合使用此技术-但对于上述表来说可能非常有用。
翻译自: https://thenewcode.com/1175/Create-a-Responsive-Pivot-Table