От автора: не так давно твит Smashing Magazine привлек внимание к моей статье по созданию элегантной таблицы с помощью OpenType. Спасибо, Smashing Magazine. Один комментатор справедливо заметил, что таблица была неадаптивной: при сужении окна браузера данные отсекались. Я не мог изменить таблицу, как в предыдущих примерах: порядок и направление данных в ней важны и не должны обрезаться. Однако есть другое решение.
В Microsoft Excel и других табличных приложениях есть функция под названием «сводные таблицы», которая меняет строки и столбцы местами. Подобный эффект можно реализовать на веб-страницах с помощью JavaScript для таблиц определенного вида. Например, для таблицы сверху.
Начинаем с разметки
Разметка таблицы похожа на таблицу из примера с OpenType, только здесь добавляются id и класс (необязательные закрывающие теги были удалены для упрощения кода).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<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> |
CSS тоже очень похож. Я написал этот пример на Sass:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
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; } |
Поворот строк и столбцов
Текущая структура таблицы записана в JS в переменную fulltable. Без JS таблица будет отображаться, но не будет поворачиваться.
1 2 3 4 5 6 7 8 9 |
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; |
Во всех переменных хранится часть таблицы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
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"); } } |
Функция pivotTable меняет строки и колонки местами. Ячейки заголовков, которые были слева, перемещаются наверх. Чисто семантически (и с точки зрения перспективы) ничего не меняется, меняется только вид.
После переворота таблицы класс меняется с large на small. Перевернутая версия структуры таблицы записывается в переменную slimTable, чтобы таблица еще раз не перевернулась при изменении размера вьюпорта.
Функция pivotTable запускается после загрузки страницы:
1 |
pivotTable(); |
Нам не нужно проверять вызов функции pivotTable каждый раз при изменении размера вьюпорта (это сильно ударит по производительности), поэтому я принудительно понизил время повторного запуска до 200 миллисекунд при срабатывании события resize:
1 |
window.addEventListener("resize", throttle( pivotTable, 200 )); |
Замедление делается через функцию:
1 2 3 4 5 6 7 8 9 10 11 12 |
function throttle (callback, limit) { var wait = false; return function () { if (!wait) { callback.call(); wait = true; setTimeout(function () { wait = false; }, limit); } } } |
Заключение
Техника не подходит для всех таблиц (в которых слишком много столбцов и строк), но может пригодиться для таблиц, как в нашем примере.
Источник: //thenewcode.com/
Редакция: Команда webformyself.