Справочная информация : я пишу приложение на vanilla JS, которое может динамически генерировать и обновлять свойства CSS-сетки.В частности, меня интересует настройка grid-template-areas
динамически.Этот пример может оказаться запутанным, поэтому вот ссылка CodeSandbox на текущее состояние проекта .
Ожидаемое поведение : я могу установить этисвойства на начальном рендере без проблем.Код для этого выглядит примерно так:
function GridMap(targetElement, {
aspectWidth,
aspectHeight,
density,
defaultTrackName = `x`
}) {
/* output: [`x x`, `x x`] */
this.areaMap = Array.from(
Array(aspectHeight)
.map(() => `${defaultTrackName} `
.repeat(aspectWidth)
.trim()
)
)
/* assign CSS grid properties to target element */
this.targetElement.style.display = `grid`
this.targetElement.style.gridTemplateAreas = this.areaMap
.map(row => `"${row}"`) // output: [`"x x"`, `"x x"`]
.join(` `) // output: `"x x" " x x"`
}
const target = document.getElementById(`target`)
const grid = new GridMap(target, {
aspectWidth: 2,
aspectHeight: 2,
density: 1,
})
Что приводит к следующему элементу:
<div id="target" style="display: grid; grid-template-areas: "x x" "x x";"></div>
Проблема : приведенный выше код работает при начальном рендере .Это сгенерирует правильный элемент, как я покажу выше.Но когда я пытаюсь сделать это впоследствии с другими (динамически генерируемыми) свойствами, элемент не обновляется.С этого момента трудно выделить код, чтобы привести хороший пример, поэтому - это проект CodeSandbox .Вот как выглядит рассматриваемый код:
function Entity({ trackName, shape }) {
this.trackName = trackName
this.shape = shape
.split(`\n`)
.filter(track => track)
.map(track => track.trim())
.filter(track => track)
}
grid.placeEntity = function placeEntity(
{ x = 0, y = 0 },
{ shape, trackName },
) {
let currentEntityRow = 0
grid.areaMap = grid.areaMap.map((row, i) => {
if (currentEntityRow < shape.length) {
if (i >= y) {
row = row.split(` `)
row.splice(
x,
shape[currentEntityRow].split(` `).length,
...shape[currentEntityRow].split(` `).map(() => trackName),
)
row = row.join(` `)
currentEntityRow += 1
}
}
return row
})
grid.update()
}
const entity = new Entity({
trackName: `entity`,
shape: `
o o
o
`
})
grid.placeEntity({ x = 1, y = 1 }, entity)
Глядя на вывод консоли в моем примере CodeSandbox , вы видите, что новый grid.areaMap
действительно генерируется.Но по какой-то причине при попытке обновить его с помощью grid.placeEntity()
обновления не отражаются во вновь отображаемом элементе.
Что я пробовал :
- Избавляемся от всего вызова
grid.placeEntity
и: - ... прямо устанавливаем
element.style.gridTemplateAreas
на что-то простое, например "foo bar" "hello world"
. Это работает, как и ожидалось . - ... непосредственно устанавливая
element.style.gridTemplateAreas
точно такую же строку, которую я генерирую в приведенном выше примере. Это не работает! Это говорит мне, что есть проблема с тем, как я генерирую grid.areaMap
, но я не могу указать на эту проблему.