- JavaScript: сортировка строк в HTML-таблице
- Создаем таблицу с функцией сортировки
- 5 последних уроков рубрики «Разное»
- Как выбрать хороший хостинг для своего сайта?
- Как разместить свой сайт на хостинге? Правильно выбранный хороший хостинг — это будущее Ваших сайтов
- Разработка веб-сайтов с помощью онлайн платформы Wrike
JavaScript: сортировка строк в HTML-таблице
Хоть в этой таблице задано лишь три строки (если не считать строки-заголовка), в задаче предупреждают, что решение должно быть для таблицы с любым количеством строк.
Нужно отметить, что в текстовом исходнике HTML-страницы в песочнице для нашей задачи теги
ине прописаны (поэтому я отметил их серебристым цветом). Но по правилам языка HTML они обязательно должны быть (секция tbody в таблице по правилам HTML может быть одна или их может быть несколько), поэтому браузер (у меня — «Microsoft Edge» на базе движка «Chromium») добавляет их сам. В этом можно убедиться, запустив для загруженной HTML-страницы с данной HTML-таблицей инструмент «Elements» из инструментов разработчика (F12).
Выглядеть эта HTML-таблица в браузере может по-разному, в зависимости от стилизации с помощью языка CSS. Например, на отдельной странице обсуждаемой задачи в обсуждаемом учебнике эта HTML-таблица показана почти что без стилизации и выглядит некрасиво, примерно так:
Имя | Фамилия | Возраст |
---|---|---|
Джон | Смит | 10 |
Пётр | Браун | 15 |
Анна | Ли | 5 |
А на странице раздела 1.7 «Изменение документа» обсуждаемого учебника, в том месте, где описывается эта же задача, данная HTML-таблица выглядит гораздо лучше, примерно так:
В принципе, внешний вид тестовой HTML-таблицы не относится к сути задания. Однако, мне хотелось, чтобы тестовая HTML-таблица выглядела красиво. Поэтому я посмотрел стили обсуждаемого учебника и описал их (те из них, которые относятся к внешнему виду нашей тестовой HTML-таблицы) в заголовочной части нашей HTML-страницы:
table < width: 100%; border-collapse: collapse; font-size: 13px; font-family: "Segoe UI"; >tr:nth-child(2n) < background: #f9f9f9; >tr < border-bottom: 1px solid #ccc; >td, th < padding: 2px 1em 2px 5px; >th
Тут стоит отметить псевдокласс :nth-child (для меня он был в новинку). В данном описании стилей с помощью этого псевдокласса определяется цвет фона ( #f9f9f9 ) каждой четной строки (тег tr ) тестовой HTML-таблицы. При этом нужно иметь в виду, что нумерация строк начинается с единицы. То есть первой строкой является заголовочная строка нашей HTML-таблицы, она нечетная, поэтому ее фон имеет цвет по умолчанию (в данном случае — белый). Вторая строка — это строка, содержащая значения «Джон», «Смит» и «10», она чётная, поэтому ее фон — серого ( #f9f9f9 ) цвета. И так далее. Тут подробнее:
Итак, в заданной HTML-таблице по условиям задачи требуется отсортировать строки (то есть переставить их местами) по столбцу «Имя».
В первую очередь я решил выбрать все строки (HTML-элементы tr ) заданной HTML-таблицы. Рука потянулась к методу querySelectorAll , описанному в подразделе 1.4 «Поиск: getElement*, querySelector*» второй части обсуждаемого учебника. Но тут я вспомнил, что для HTML-таблиц существуют более удобные способы работы с частями этих таблиц. Они были описаны в подразделе 1.3 «Навигация по DOM-элементам» второй части обсуждаемого учебника. Например, получить коллекцию строк HTML-таблицы можно с помощью свойства rows HTML-таблицы. При построении тестовой HTML-таблицы ей был дан идентификатор table , поэтому получить коллекцию строк этой таблицы можно с помощью выражения table.rows .
В учебнике было сказано, что получаемая таким образом коллекция HTML-элементов не является массивом (это псевдомассив). А это значит, что к коллекции HTML-элементов нельзя будет применить методы массивов. А мы, ведь, хотим отсортировать строки HTML-таблицы, следовательно, нам нужно отсортировать полученную коллекцию строк HTML-таблицы. Можно, конечно, самому написать метод сортировки для коллекции. Но зачем, если метод сортировки уже написан, хоть и для массива? Просто преобразуем нашу коллекцию строк HTML-таблицы в массив, а затем используем готовый метод сортировки массива. Пишем код:
1.
let arr = Array.from( table.rows ); // преобразуем коллекцию в массив arr.sort(); // используем готовый метод сортировки массива
В этом коде используется сортировка массива по умолчанию (для метода сортировки не задан параметр). В этом случае элементы массива приводятся к строке, а затем происходит их сравнение. В нашем случае элементы массива являются объектами, HTML-элементами tr . При преобразовании каждого из этих объектов в строку получится одна и та же строка — «[object HTMLTableRowElement]» . Метод сортировки посчитает все элементы массива равными и сортировки не произойдет. Поэтому нам следует прописать функцию, определяющую порядок сортировки, и передать ее в метод сортировки массива первым параметром. Меняем код:
2.
let arr = Array.from( table.rows ); arr.sort( (a, b) => < let str = a.cells[0].textContent; let str2 = b.cells[0].textContent; return str.localeCompare(str2); >);
Здесь функция, определяющая порядок сортировки, не имеет имени и задана стрелочной функцией. У этой функции два входящих параметра — a и b , это два элемента массива, сравниваемых при сортировке массива, выполняемой методом sort . То есть переменные a и b являются в данном случае HTML-элементами tr .
По условиям задачи для сравнения строк нашей HTML-таблицы следует использовать значения столбца «Имя», а этот столбец состоит из первых ячеек (HTML-элементов td или th ) каждой строки нашей HTML-таблицы. Коллекцию этих ячеек можно получить с помощью свойства cells строки HTML-таблицы, это было описано в уже упомянутом подразделе 1.3 «Навигация по DOM-элементам» второй части обсуждаемого учебника. Первая ячейка каждой строки нашей HTML-таблицы и есть cells[0] , а ее текстовое содержимое — cells[0].textContent . Таким образом в переменных str и str2 мы получаем текстовые строки, каждая из которых представляет свой объект [object HTMLTableRowElement] , эти переменные мы и будем использовать для сравнения с помощью метода localeCompare .
Наш код уже отсортировал строки тестовой HTML-таблицы в массиве. Осталось лишь вставить их из массива обратно в тестовую HTML-таблицу. Сделаем это с помощью уже ставшего привычным (я его применял ранее для решения нескольких задач) метода append . В предыдущих постах я его применял для вставки одного HTML-элемента за раз, но, ведь, им можно вставлять сразу несколько HTML-элементов с помощью оператора расширения (многоточие). Меняем код:
3.
let arr = Array.from( table.rows ); arr.sort( (a, b) => < let str = a.cells[0].textContent; let str2 = b.cells[0].textContent; return str.localeCompare(str2); >); table.append(. arr);
Может возникнуть вопрос: если мы только вставляем новые строки в тестовую HTML-таблицу и не удаляем старые, то всего строк теперь должно стать не четыре, а восемь (каждая исходная строка дублируется)? На самом деле, нет, потому что метод append (как и его коллеги) сначала удаляет HTML-элемент со старого места, а затем вставляет его на новое место. То есть фактически вставляются не новые элементы, а исходные.
Наш код отсортировал строки заданной HTML-таблицы и результат отобразился в браузере. Однако, вместе со всеми отсортировалась и заголовочная строка, которая, по идее, должна остаться на своем месте, вверху HTML-таблицы. Я решил отследить эту строку внутри функции, определяющей порядок сортировки, и сделать так, что она не будет двигаться со своего места. Меняем код:
4.
let arr = Array.from( table.rows ); arr.sort( (a, b) => < if (a.cells[0].tagName == "TH" || b.cells[0].tagName == "TH") return 0; let str = a.cells[0].textContent; let str2 = b.cells[0].textContent; return str.localeCompare(str2); >); table.append(. arr);
Это сработало, теперь заголовочная строка остаётся на своем месте. Однако, авторы задачи в своем решении предложили более изящный способ:
5.
let arr = Array.from( table.rows ); arr = arr.slice(1); arr.sort( (a, b) => < let str = a.cells[0].textContent; let str2 = b.cells[0].textContent; return str.localeCompare(str2); >); table.append(. arr);
Метод slice возвращает новый массив, в данном случае — без первого элемента (который и является заголовочной строкой нашей HTML-таблицы), и полученный массив записывается на место старого, в переменную arr . Таким образом, заголовочная строка вообще не принимает участия в сортировке и не перемещается на новое место (не попадает в руки метода append ).
Теперь, казалось бы, всё в порядке. Но нет. Если просмотреть полученную HTML-страницу с помощью инструмента «Elements» из инструментов разработчика (F12) браузера, то можно увидеть, что метод append вставил HTML-элементы tr не внутрь HTML-элемента tbody (как положено по правилам языка HTML), а после него.
В некоторых случаях такое нарушение может повлиять на внешний вид страницы. Например, в случае кода из варианта 4 нашего скрипта (см. выше) собьется порядок окраски фона строк нашей тестовой HTML-таблицы: серым цветом будет окрашен фон нечетных строк (первой и третьей) вместо указанных в стиле четных (второй и четвертой). Это произойдет из-за того, что HTML-элемент tbody станет соседом HTML-элементов tr и при расчете номеров HTML-элементов в этой группе HTML-элементов он будет считаться первым (так как является первым ребенком общего для группы родителя). Таким образом, нумерация собьется и первая строка таблицы будет теперь считаться второй, вторая строка — третьей и так далее.
Чтобы поместить отсортированные строки нашей HTML-таблицы из массива обратно в HTML-элемент tbody , изменим последнюю строчку нашего кода:
6.
let arr = Array.from( table.rows ); arr = arr.slice(1); arr.sort( (a, b) => < let str = a.cells[0].textContent; let str2 = b.cells[0].textContent; return str.localeCompare(str2); >); table.tBodies[0].append(. arr);
Это финальный вариант скрипта. О свойстве tBodies рассказывалось в том же подразделе 1.3 «Навигация по DOM-элементам» второй части обсуждаемого учебника. Секций tbody , как уже упоминалось, в HTML-таблице может быть несколько. В нашем случае такая секция одна.
Создаем таблицу с функцией сортировки
В этом уроке Вы узнаете как сделать красивую таблицу с данными с возможностью сортировки по любому столбцу.
Это довольно полезная штука, особенно когда таблицы очень большие.
Первым делом подключаем стили оформления между тегами :
Внешний вид таблицы можно легко изменить, если покопаться в стилях.
Далее создаем непосредственно саму таблицу:
Name
Phone
Email
Zip
Birthdate
Last Access
Rating
Done
Salary
Score
1
Ezekiel Hart
(627) 536-4760
tortor@est.ca
53082
12/02/1962
March 26, 2009
-7
7%
$73,229
6.9
.
Вместо многоточия должны быть ряды с информацией. Как Вы видите столбцу ID мы придали класс «nosort», таким образом мы убрали возможность сортировки для него. Всей таблице был присвоен класс «sortable».
Далее идет блок с кнопками навигации по таблице:
Entries Per Page