【发布时间】:2018-10-07 07:09:52
【问题描述】:
背景:我正在用 vanilla JS 编写一个可以动态生成和更新 CSS 网格属性的应用程序。特别是,我对动态设置grid-template-areas 很感兴趣。这个例子可能很复杂,所以here's a CodeSandbox link to the current state of the project。
预期行为:我可以在初始渲染时设置这些属性,没有任何问题。代码如下所示:
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>
问题:上面的代码在初始渲染时工作。它将生成一个正确的元素,如我上面所示。但是当我之后尝试使用不同的(动态生成的)属性时,元素不会得到更新。从这一点开始,很难隔离代码来给出一个很好的例子,所以here's the project so far on 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 example 中的控制台输出,您会看到确实生成了新的grid.areaMap。但由于某种原因,当尝试通过grid.placeEntity() 对其进行更新时,更新不会反映在新渲染的元素中。
我的尝试:
- 摆脱整个
grid.placeEntity呼叫并且:- ...直接将
element.style.gridTemplateAreas设置为"foo bar" "hello world"之类的简单对象。 这按预期工作。 - ...直接将
element.style.gridTemplateAreas设置为我在上面的示例中生成的完全相同的字符串。 这不起作用!这告诉我生成grid.areaMap的方式存在问题,但我无法指出该问题。
- ...直接将
【问题讨论】:
标签: javascript css css-grid