动态排版

6 个月前
12

问题一

因为不用考虑每一个区域的大小,而且只能在一个矩形容器中放入三种矩形内容,所以排版方式是有穷的,共 36 种。

计算方式如下:

  1. 布局组合:

    一行三列、上一下二、上二下一、左一右二、左二右一、三行一列。

    共 6 种布局组合。

  2. 文本、图片、列表的排列可能:

    A(3,3) = 6

  3. 两者相乘,得到 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-areagrid-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>

效果如图:

效果图

效果图
  • Loading...
  • Loading...
  • Loading...
  • Loading...