JavaScript | Как получить элементы одной линии в блоке с CSS свойством «display: grid» с «grid-template-columns: repeat(auto-fit, …)»?

JavaScript | Как получить элементы одной линии в блоке с CSS свойством «display: grid» с «grid-template-columns: repeat(auto-fit, …)»?

Свойство «grid-template-columns» указывает список дорожек для столбцов сетки, а свойство «grid-template-rows» указывает список дорожек для строк сетки. Эти свойства определяют в виде списка дорожек, разделенных пробелами, имена линий и функции определения размеров дорожек сетки.

Свойство «grid-template-columns» в родительском блоке отвечает за то, сколько столбцов должно быть в сетке на HTML-странице. Если используем функцию «repeat()«, где в качестве первого параметра указываем значение «auto-fit«, то мы фактически не знаем сколько элементов получится в одной линии сетки, а также мы не знаем сколько столбцов будет создано под каждый конкретный размер экрана пользователя. Сетка адаптивная.

Но мы всё же хотим получить элементы одной линии, чтобы силами JavaScript создать удобный пользовательский функционал для манипулирования с элементами в линиях сетки. Как это сделать?

 

Сколько линий (rows) создано в сетке (grid) на HTML-странице?

Думаю проще начать решение нашей задачи именно с этого вопроса. Что будет объединять элементы одной линии?

Их будет объединять смещение относительно верхней линии страницы в пикселях. Каждый объект HTML-элемента хранит в себе свойство «offsetTop«. Если сетка построилась, то у элементов одной линии значение свойства «offsetTop» будет одинаково.

Это значит, что для всех дочерних элементов блока мы можем получить уникальные значения этого ключа.

У меня есть несколько сеток на 3906 дочерних элементов. Просто отберу все вложенные элементы по сеткам:

[...document.querySelectorAll('.a')]
CSS-сетка на 3906 элементов с repeat() auto-fit
CSS-сетка на 3906 элементов с repeat() auto-fit

Каждый объект хранит в себе значение свойства «offsetTop«.

Одинаковые значения offsetTop для элементов одной линии CSS-сетки - JavaScript
Одинаковые значения offsetTop для элементов одной линии CSS-сетки — JavaScript

Количество линий будет равно количеству уникальных значений для всех элементов сетки.

Я выберу только одну сетку и её вложенные элементы:

[...document.querySelector("#db-wordforms-result > div:nth-child(5)").children].filter(i=>[...i.classList].includes('a'))

По итогу у меня получится 593 элемента, но это никак не повлияет на свойство «offsetTop«.

Теперь пробежимся по всем значения, соберём их в массив и создадим набор.

[...new Set([...document.querySelector("#db-wordforms-result > div:nth-child(5)").children].filter(i=>[...i.classList].includes('a')).map(i=>i.offsetTop))]

Получим массив на 119 чисел, что соответствует делению 593 на 5 = 118,6. Это значит, что на текущий момент у нас построено 119 линий с элементами.

Уникальные значения верхнего отступа в пикселях для линий CSS-сетки
Уникальные значения верхнего отступа в пикселях для линий CSS-сетки

 

Получение объектов одной линии сетки

Теперь можно легко сгруппировать элементы по линиям и оформить это в виде массива из массивов.

[...new Set([...document.querySelector("#db-wordforms-result > div:nth-child(5)").children].filter(i=>[...i.classList].includes('a')).map(i=>i.offsetTop))]
.map(i=>[...document.querySelectorAll('.a')].filter(el=>el.offsetTop==i))
Сгруппировали элементы линий в динамической CSS-сетке в массив JavaScript
Сгруппировали элементы линий в динамической CSS-сетке в массив JavaScript

Запрос выполняется долго, так как я обхожу все 3906 объектов для группировки. Эти лишний шаг так как можно ограничиться только объектами этой сетки. Здесь просто для примера в одну линию кода.

В идеале нужно писать отдельную функцию с достаточным количеством переменных, которая будет реагировать на изменение размеров экрана, масштаба и т.п..