首页 / 中文教程 / 教程

Bricks 查询循环布局切换开关

这篇教程教你:当用户点击查询循环上方的图标切换按钮时,动态改变查询循环容器的布局。

Ray Chan·2026-08-12·约 3 分钟

这篇教程教你:当用户点击查询循环上方的图标切换按钮时,动态改变查询循环容器的布局。

引言

想让用户自己从几种布局方案里挑一个来查看你的查询循环网格吗?

这篇教程将演示如何做到这一点——不需要外部插件、不需要 JS 库、也不需要复制内容(复制内容真的会伤 SEO 内容优化,对吧?),只需要在页面里加一小段自定义代码。

DOM 结构

按照下面的结构重建,并按下图添加类名。注意:post 容器的样式/结构完全由你决定——它不影响脚本运行。

**重要:一定要给默认选中的切换按钮加上 .toggle-layout--active 类。**这个类的样式随你喜欢。

在每个布局切换按钮上,添加下面的属性

data-layout 属性:选一个能描述该布局的唯一名称作为值。示例中我们用了 listlist-two-colgrid。这些名字会被当作类名,加到查询容器上,用来针对特定布局给内部元素写样式。

data-layout-col 属性:填入将应用到查询容器的列数

JavaScript

把下面的代码插入页面。个人推荐使用条件加载脚本的方法

// 等 DOM 完全加载后再运行脚本 - 避免阻塞渲染
window.addEventListener('DOMContentLoaded', () => {

   // 查找所有带布局切换的容器
   const containers = document.querySelectorAll('.loop-ctn-w-layout-toggles');

   // 检查页面上是否有带布局切换的容器
   if (containers.length < 1) return console.log('There is no container with layout toggles on this page. Double check you correctly added the .loop-ctn-w-layout-toggles class on the main container.');

   // 遍历所有容器
   containers.forEach(container => {

      // 查找切换按钮容器
      const toggleContainer = container.querySelector('.toggle-container');

      // 检查是否有切换按钮容器
      if (!toggleContainer) return console.log('There is no toggle container. Double check you correctly added the .toggle-container class on the toggle container.');

      // 查找查询容器
      const queryContainer = container.querySelector('.query-container');

      // 检查是否有查询容器
      if (!queryContainer) return console.log('There is no query container. Double check you correctly added the .query-container class on the query container.');

      // 查找所有切换按钮
      const toggles = toggleContainer.querySelectorAll('.toggle-layout');

      // 查找当前激活的切换按钮
      const activeToggle = toggleContainer.querySelector('.toggle-layout--active');

      // 加载时设置默认布局
      queryContainer.classList.add(activeToggle.dataset.layout);

      // 检查是否有切换按钮
      if (toggles.length < 1) return console.log('There are no layout toggles. Double check you correctly added the .toggle-layout class on each toggle.');

      // 创建空数组,存放所有不同的布局类
      let layouts = [];

      // 把所有布局类填入数组
      toggles.forEach(toggle => {

         // 检查 data-layout 属性是否正确设置
         if (!toggle.dataset.layout) return console.log('The attribute data-layout has not been correctly set on the toggles.');
         layouts.push(toggle.dataset.layout);
      });

      // 遍历每个切换按钮
      toggles.forEach(toggle => {

         // 给切换按钮添加点击事件监听
         toggle.addEventListener('click', (e) => {

            // 阻止默认行为
            e.preventDefault();

            // 读取 data-layout 属性
            const layout = toggle.dataset.layout;

            // 如果已经是当前布局,避免重复执行动画
            if (queryContainer.classList.contains(layout)) return;

            // 从属性读取列数
            const col = toggle.dataset.layoutCol;

            // 检查 data-layout-col 属性是否正确设置
            if (!toggle.dataset.layoutCol) return console.log('The attribute data-layout-col has not been correctly set on the toggles.');

            // 移除现有的激活类
            toggles.forEach(el => el.classList.remove('toggle-layout--active'));

            // 给点击的切换按钮添加激活类
            toggle.classList.add('toggle-layout--active');

            // 从查询容器移除已有布局类
            queryContainer.classList.remove(...layouts);

            setTimeout(() => {
               // 给查询容器添加自定义布局类,方便进一步定制内部元素样式
               queryContainer.classList.add(layout);

               // 修改网格列数
               queryContainer.style.setProperty('--grid-column-count', col);
            }, 100);
         })
      })
   })
})

CSS

把下面的 CSS 插入页面:

.loop-ctn-w-layout-toggles .query-container {
   /* 下面的变量按需设置 */
   --grid-layout-gap: 3rem;
   --grid-column-count: 4;
   --grid-item--min-width: 280px;
   /* 变量结束 - 不要修改下面的数值 */

   display: grid;
   grid-gap: var(--grid-layout-gap);
}

@media screen and (min-width: 768px) {
   .loop-ctn-w-layout-toggles .query-container {
      --gap-count: calc(var(--grid-column-count) - 1);
      --total-gap-width: calc(var(--gap-count) * var(--grid-layout-gap));
      --grid-item--max-width: calc((100% - var(--total-gap-width)) / var(--grid-column-count));
      grid-template-columns: repeat(auto-fill, minmax(max(var(--grid-item--min-width), var(--grid-item--max-width)), 1fr));
   }

   /* 可选动画 */
   body.bricks-is-frontend .loop-ctn-w-layout-toggles .query-container .post-container {
      animation: none;
      opacity: 0;
   }

   body.bricks-is-frontend .loop-ctn-w-layout-toggles .query-container.list .post-container,
   body.bricks-is-frontend .loop-ctn-w-layout-toggles .query-container.list-two-col .post-container,
   body.bricks-is-frontend .loop-ctn-w-layout-toggles .query-container.grid .post-container {
      animation: 300ms slide-up ease-in-out forwards;
   }

   /* 可选:根据查询容器布局定制内部元素样式 */
   .loop-ctn-w-layout-toggles .query-container.list .post-container,
   .loop-ctn-w-layout-toggles .query-container.list-two-col .post-container {
      flex-direction: row;
   }

   .loop-ctn-w-layout-toggles .query-container.list .post-container img {
      width: 30%;
      max-height: 100%;
   }

   .loop-ctn-w-layout-toggles .query-container.list-two-col .post-container img {
      width: 45%;
      max-height: 100%;
   }
}

@keyframes slide-up {
   0% {
      opacity: 0;
      transform: translateY(40px);
   }

   100% {
      opacity: 1;
      transform: translateY(0);
   }
}

重要提示:

  • 这套代码基于这篇文章里的第 2 种网格方法。你可以修改前 3 个 CSS 变量来设置默认布局样式。

  • CSS 里包含一段可选的动画代码——记得把它换成你自己的布局名

  • 这个示例中我们决定给 list 和 list-two-col 布局改 flex-direction。为此需要加几行自定义 CSS:先把布局类挂到查询容器上(如下图红色方框所示),然后定位你要改的 CSS 选择器——本例是 post 容器和特色图:

最终效果

一切设置正确的话,前端应该能看到下面的效果:

结论

这个方案只靠一段 JS + 一段 CSS 就实现了查询循环的布局切换:切换按钮用 data-layout(布局名)和 data-layout-col(列数)两个属性驱动,脚本负责给查询容器切换布局类、更新 --grid-column-count 变量,CSS 用 grid 的 auto-fill + minmax 响应式算法(最小列宽 280px、断点 768px)自动排布。不需要任何外部插件或库。

💡 译者注:原文代码块中有一行 body.[bricks](https://brickslabs.com/go/bricks)-is-frontend,是原文抓取时残留的 markdown 链接产物,实际应为 body.bricks-is-frontend(与同段其他选择器一致),翻译时已修正。

需要帮忙?

用 Bricks 建站?我接客户项目。

从快速营销站到完整的 Bricks 建站,再到从 Elementor 迁移——我都做过。本站每篇教程都来自真实项目经验。告诉我你的需求,一个工作日内回复。

  • Bricks 建站与改版
  • Elementor / Divi → Bricks 迁移
  • Bricks → Astro / headless 性能升级
  • 速度优化,PageSpeed 95+ 目标