动态排版
6 个月前
12
问题一
因为不用考虑每一个区域的大小,而且只能在一个矩形容器中放入三种矩形内容,所以排版方式是有穷的,共 36 种。
计算方式如下:
布局组合:
一行三列、上一下二、上二下一、左一右二、左二右一、三行一列。
共 6 种布局组合。
文本、图片、列表的排列可能:
A(3,3) = 6
两者相乘,得到 36 种排版.
问题二
可以用一个嵌套数组表示排版结构,外层数组表示行,内层数组表示每一行包括的列。例如:
// 左一右二布局
[
[
{
type: 'img', // 图片
content: 'https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg', // 图片链接
},
{
type: 'list', // 列表
content: ['apple', 'banana', 'orange']
},
],
[
{
type: 'img', // 图片
content: 'https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg', // 图片链接
},
{
type: 'text', // 文本
content: 'Hello, world! Hello, world!', // 文本内容
},
],
]
问题三
通过 grid 布局以及 grid-area
和 grid-template-areas
可以实现。
完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
p {
margin: 0;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
#container {
width: 50vw;
height: 50vw;
margin: 0 auto;
display: grid;
}
#text {
background-color: burlywood;
grid-area: text;
}
#list {
background-color: skyblue;
grid-area: list;
}
#img {
grid-area: img;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="container">
<p id="text"></p>
<img id="img" />
<ul id="list"></ul>
</div>
<script>
// 假设后端返回的排版数据如下,左一右二布局
const res = [
[
{
type: 'img', // 图片
content: 'https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg', // 图片链接
},
{
type: 'list', // 列表
content: ['apple', 'banana', 'orange']
},
],
[
{
type: 'img', // 图片
content: 'https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg', // 图片链接
},
{
type: 'text', // 文本
content: 'Hello, world! Hello, world!', // 文本内容
},
],
]
let areas = []
// 遍历设置元素内容
res.forEach(row => {
let rowAreas = []
row.forEach(item => {
const { type, content } = item
rowAreas.push(type)
const el = document.getElementById(type)
switch (type) {
case 'text': {
el.textContent = content
break
}
case 'img': {
el.src = content
break
}
case 'list': {
if (!el.hasChildNodes()) {
content.forEach(c => {
const li = document.createElement('li')
li.textContent = c
el.appendChild(li)
})
}
}
}
})
areas.push(rowAreas)
})
// 设置 `grid-template-areas`
const container = document.getElementById('container')
container.style.gridTemplateAreas = areas.map(row => `'${row.join(' ')}'`).join(' ')
</script>
</body>
</html>
效果如图:

效果图