От автора: добавление и удаление товаров из корзины – довольно распространенный UI шаблон. Часто он создается с помощью фреймворка (или двух, или трех…). На этой неделе я понял, что этот шаблон можно написать на CSS и чистом JavaScript.
Основа
Фундаментальная структура таблицы представлена в HTML и отображается без каких-либо UI элементов. То есть если JS не сработает или будет заблокирован, пользователь будет видеть список, но не сможет его редактировать.
1 2 3 4 5 6 7 8 9 |
<table id="zen"> <caption>AMD Zen Processors</caption> <thead> <tr><th>Name<th>Speed<th>Cores<th>Threads<th>Price <tbody> <tr><td>SR7<td>3.5Ghz<td>8<td>16<td>$499 <tr><td>SR7<td>3.2GHz<td>8<td>16<td>$349 <tr><td>SR5<td>3GHz<td>6<td>12<td>$250 </table> |
Обратите внимание на то, что я использую полностью валидные HTML5 сокращения для экономии пространства в примере. Кроме того, спецификации и цены на новое поколение процессоров AMD сейчас неизвестны. С таблицей ассоциируется несколько CSS правил:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#zen { border-collapse: collapse; } #zen tr td, #zen tr th { padding: .4rem; } #zen tr td:nth-of-type(3), #zen tr td:nth-of-type(4) { text-align: center; } #zen thead { border-bottom: 2px solid #333; } #zen tbody tr { border-bottom: 1px solid #ddd; } |
Добавляем кнопки
Кнопки вставляются в виде отдельной ячейки, которая присоединяется справа от каждой строки в теле таблицы:
1 2 3 4 |
let procRows = zen.querySelectorAll("tbody tr"); for (let i = 0; i < procRows.length; i++) { procRows[i].innerHTML += '<td><button title="Remove"></td>'; } |
В CSS у кнопок прописан фон из SVG изображения мусорной корзины:
1 2 3 4 5 6 7 8 9 10 |
#zen button { width: 36px; height: 36px; background-image: url(trashcan.svg); margin-left: 1rem; border: none; background-position: center 4px; background-repeat: no-repeat; background-size: 25px 25px; opacity: .6; transition: .5s; } |
Также прописано состояние :hover, которое изменяет вид кнопки при наведении на нее курсора мыши:
1 2 3 4 |
tbody tr button:hover { opacity: .9; cursor: pointer; } |
Скрипт использует принцип всплытия событий для отслеживания клика в теге tbody таблицы. Если клик был произведен по тегу button, скрипт найдет ячейку, в которой лежит кнопка, затем найдет строку, в которой лежит ячейка, и присвоит ей класс. После этого кнопка удаляется.
1 2 3 4 5 6 7 |
zen.querySelector("tbody").addEventListener("click", function(e) { if (e.target.nodeName == "BUTTON") { let cell = e.target.parentNode; cell.parentNode.classList.add("hidden"); e.target.remove(); } }) |
Добавляем плавности
CSS не может анимировать высоту элемента. Однако высота td, хранящая текстовый контент, вычисляется по двум параметрам:
font-size текста;
padding ячейки таблицы.
… и мы можем анимировать оба свойства:
1 2 3 4 5 6 |
@keyframes hide { to { font-size: 0; padding: 0; } } |
Эта последовательность анимаций вызывается при добавлении строке таблицы класса hide:
1 2 3 4 5 6 7 |
tr.hidden td { animation: hide 1s 1s forwards; } tr.hidden { opacity: 0; border-bottom: none; } |
Анимация длится 1 секунду с задержкой в 1 секунду. Можно плавно прятать строки таблицы, добавив свойство transition к ним:
1 |
#zen tr { transition: .8s opacity; } |
Заключение
Скрипт и CSS создают простую анимацию удаления выбранной строки из таблицы. Если хотите полностью удалить строку из DOM (а не просто прятать ее), можно сделать это после завершения анимации. Посмотрите CodePen демо по этой статье.
Источник: //thenewcode.com/
Редакция: Команда webformyself.