Bricks Popup Builder 与 Interactions 交互实战:弹窗、触发器与 JavaScript 钩子
Bricks 的 Popup Builder 让你创建完全自定义的弹窗——本质上它是一个模板类型为 Popup 的 Bricks 模板;Bricks 在前端渲染弹窗 HTML、默认隐藏,再通过 Interactions 或 JavaScript 打开 / 关闭。而 Interactions(Bricks 1.6 起)是一套“当某件事发生时运行某个动作”的系统。两者常配合使用:用 Interactions 触发弹窗、用弹窗自身的交互做后续动作。
本文合并官方两篇文档——Popup Builder 与 Interactions——给出一份可直接照做的实操指南。
Popup Builder 是什么
弹窗(popup)是一种 Bricks 模板,模板类型为 Popup。Bricks 在前端渲染弹窗 HTML,默认隐藏,并通过 Interactions 或 JavaScript 打开、关闭。
适合用弹窗的场景:模态框、订阅表单、退出意图(exit-intent)优惠、快速预览(quick view)、地图信息框,以及查询循环里的上下文内容。
创建弹窗模板
- 新建一个模板,选择 Popup 模板类型。
- 保存模板,然后用 Bricks 编辑它。
弹窗模板和普通的页面模板看起来不同:
- 弹窗内容在画布上居中。
- 模板设置里多了一个 Popup 分组。
- 模板不使用 Populated Content。
像搭其它 Bricks 布局一样搭弹窗主体:往画布上加 section、container、form、button、icon、image 或动态数据。
弹窗可用性与模板条件
模板条件决定 Bricks 在哪些页面渲染弹窗模板。打开 Settings > Template Settings > Conditions,选择弹窗应当可用的页面。
例如:一个能从全局页脚打开的订阅弹窗,通常需要类似“整站(Entire website)”这样的条件;而商品快速预览弹窗可能只需要在商店页或商品归档页可用。
如果当前页面没有渲染某个弹窗,对应的交互就无法打开它——因为 DOM 里没有这个弹窗元素。如果某个页面在 Page Settings 里启用了 Disable popups,Bricks 不会渲染页面弹窗。同一个页面上可以渲染多个弹窗模板。
Popup 设置
弹窗专属设置在 Settings > Template Settings > Popup 下。你也可以在 Theme Styles 的 Popup 控件组里定义全局弹窗默认值,单个弹窗的模板设置可以覆盖这些默认值。
主要弹窗设置包括:
- Padding:弹窗包裹层的 padding。
- Align main axis 与 Align cross axis:在视口内定位弹窗内容。
- Close on:选择“点击背景关闭”“ESC 键关闭”“都不”“或默认的点击背景 + ESC”。
- Z-index:控制弹窗层叠。
- Scroll (body):弹窗打开时允许页面 body 滚动;若关闭,Bricks 会在弹窗打开时给 body 加上
no-scroll。 - Scroll to top:打开时把弹窗内容滚到顶部。
- Disable auto focus:阻止 Bricks 聚焦弹窗内第一个可聚焦元素。
- Fetch content via AJAX:按需渲染弹窗内容,而不是放在初始 DOM 里。
- AJAX loader:为 AJAX 弹窗选择加载动画,以及可选的 selector、color、scale。
- Breakpoints:选择弹窗允许显示的位置。
- Backdrop:配置或禁用背景遮罩。
- Content:给
.brx-popup-content包裹层加样式。 - Popup limit:限制弹窗可打开的次数。
在前端,Bricks 会把键盘焦点“困”在打开的弹窗内、关闭后恢复焦点、根据 Close on 设置支持 ESC / 点击背景关闭,并派发弹窗 JavaScript 事件。
点击弹窗外部或按 ESC 只有在 Close on 设置包含该行为时才会关闭弹窗。若设为 None,需自己加关闭交互或 JavaScript。
弹窗交互(Show/Hide popup 触发器)
在弹窗设置面板的下方,Interactions 分组让弹窗对事件做出反应。弹窗模板交互使用与元素相同的交互系统,外加两个弹窗专属触发器:
- Show popup:本弹窗打开后运行。
- Hide popup:本弹窗关闭后运行。
当你希望弹窗自身做后续动作(如启动动画、写入存储、或在打开/关闭后更新另一个元素)时使用这两个触发器。
对于 Hide popup,目标应设为 CSS 选择器,而非直接选弹窗——因为该触发器在弹窗已经关闭后才运行。
大多数弹窗是由另一个元素上的交互打开的。例如给 Button 加一个 Click 交互,把 Target 设为 Popup、选择弹窗模板、用 Show element 动作。一个常见的自动弹窗用 Content loaded 触发器。如果没有弹窗自身的交互、也没有别的元素交互打开它,弹窗会一直保持隐藏。
弹窗开关生命周期
Bricks 打开弹窗时,前端流程是:
- 按模板 ID 或元素节点解析弹窗元素。
- 检查弹出限制。
- 检查弹窗断点规则。
- 移除
hide类。 - 除非允许 body 滚动,否则给 body 加
no-scroll。 - 如果弹窗配置为 AJAX,则抓取 AJAX 弹窗内容。
- 若抓到了内容,插入到
.brx-popup-content。 - 仅对被插入的 AJAX 内容派发
bricks/ajax/popup/loaded。 - 派发
bricks/popup/open。 - 增加弹窗计数器。
Bricks 关闭弹窗时,加上 hide 类、在没有任何其它“禁止 body 滚动”的弹窗打开时移除 body 的 no-scroll,并派发 bricks/popup/close。
这个生命周期对自定义代码很重要:
- 需要新抓取的 AJAX 弹窗 DOM 存在时,监听
bricks/ajax/popup/loaded。 - 需要弹窗已打开时,监听
bricks/popup/open。 - 需要在关闭后做清理时,监听
bricks/popup/close。
弹出限制(Popup limit)
默认情况下,弹窗每次被触发都会打开。用 Settings > Template Settings > Popup > Popup limit 限制它打开的频率。Bricks 在打开前检查限制;一旦达到限制,弹窗不打开、也不派发打开事件。
四种弹出限制控件:
| 限制类型 | 浏览器存储 | 说明 |
|---|---|---|
| Per page load | window.brx_popup_{id}_total |
页面重新加载后重置 |
| Per session | sessionStorage.brx_popup_{id}_total |
浏览器会话 / 标签页存储被清除时重置 |
| Across sessions | localStorage.brx_popup_{id}_total |
一直保留直到本地存储被清除 |
| Show again after hours | localStorage.brx_popup_{id}_lastShown |
记录上次显示的时间戳,等待配置的小时数后才允许再次打开 |
页面级、会话级、跨会话级的计数器在弹窗每次成功打开时加一;基于小时数的设置则在弹窗通过限制检查时记录上次显示时间戳。
弹窗断点
弹窗断点设置控制弹窗是否允许在当前视口宽度显示。Bricks 支持两种模式:
- Start display at breakpoint:在所选断点宽度及以上显示弹窗。
- Display on breakpoints:只在所选断点范围内显示弹窗。
如果当前视口不匹配弹窗断点规则,Bricks 不会打开它。
关闭弹窗的几种方式
- 用弹窗的 Close on 设置(点击背景和 / 或 ESC)。
- 在弹窗内加一个关闭图标或按钮,给它一个 Hide element 交互,目标指向该弹窗。
- 用一个可复用的关闭元素,目标指向
.brx-popup。 - 从 JavaScript 调用
bricksClosePopup()。
示例:添加弹窗关闭图标
给弹窗加一个 Icon 元素,在 Styles > Layout > Misc 下把光标设为 pointer。打开 Icon 元素的 Interactions 面板并添加:
- 触发器:Click
- 目标:Popup
- 弹窗:当前弹窗
- 动作:Hide element
如果要在不同弹窗里复用同一个关闭图标,把它做成 Component,然后用:
- 目标:CSS selector
- CSS selector:
.brx-popup - 动作:Hide element
JavaScript 辅助函数与事件
Bricks 在前端暴露了弹窗辅助函数和自定义事件。
通过 JavaScript 打开或关闭弹窗:用 bricksOpenPopup 与 bricksClosePopup,两者都接受弹窗模板 ID 或弹窗元素节点:
bricksOpenPopup(3321)
bricksClosePopup(3321)
const popup = document.querySelector('.brx-popup[data-popup-id="3321"]')
bricksOpenPopup(popup)
bricksClosePopup(popup)
示例:按选择器打开弹窗
document.querySelectorAll('.brxe-heading, .my-custom-selector').forEach((el) => {
el.addEventListener('click', () => {
bricksOpenPopup(3321)
})
})
监听弹窗打开 / 关闭事件:用 bricks/popup/open 与 bricks/popup/close:
document.addEventListener('bricks/popup/open', (event) => {
const popupId = event.detail.popupId
const popupElement = event.detail.popupElement
if (popupId == 3321) {
console.log('3321 popup is opened')
}
})
document.addEventListener('bricks/popup/close', (event) => {
const popupId = event.detail.popupId
const popupElement = event.detail.popupElement
if (popupId == 3321) {
console.log('3321 popup is closed')
}
})
注意用 event.detail.popupId 和 event.detail.popupElement,属性是 detail 而不是 details。
查询循环里的弹窗:可以用 Template 元素在查询循环里加弹窗,弹窗内的动态数据可引用当前循环项。对于 Bricks 1.7.1 及更新版本,Bricks 能为查询循环弹窗构建“循环专属”的弹窗 HTML;更旧版本不要把交互设在 Query Loop 的 div 本身,而要设在循环项内部的元素上。
如果循环弹窗已渲染在页面上,可按查询元素 ID 和循环索引定位:
document.addEventListener('DOMContentLoaded', () => {
setTimeout(() => {
const queryId = 'vfiqrn'
const targetPopup = document.querySelector(
`.brx-popup[data-popup-loop="${queryId}"][data-popup-loop-index="7"]`
)
bricksOpenPopup(targetPopup)
}, 200)
})
那个小延迟在自定义代码元素里很有用,它给 Bricks 前端全局变量和弹窗标记留出了初始化时间。
AJAX 弹窗
AJAX 弹窗在 Bricks 1.9.4 引入。开启 Fetch content via AJAX 后,Bricks 让初始 DOM 更轻量,只在弹窗打开时才抓取内容——这对查询循环里的弹窗尤其有用(否则在初始页面加载时渲染每个弹窗的完整内容会很昂贵)。
开启 AJAX 后:
- 弹窗包裹层渲染在页面上。
- 在构建器预览之外,
.brx-popup-content一开始是空的。 - 弹窗打开时,Bricks 从 REST 端点抓取内容。
- 返回的 HTML 与动态 CSS 被插入
.brx-popup-content。 - 如果 AJAX 内容含循环 AJAX 弹窗,额外的嵌套弹窗 HTML 可被追加到 body。
AJAX 弹窗渲染支持 post、term、user 上下文。没有稳定对象 ID 的动态数据(如某些 repeater 行)不一定能作为 AJAX 弹窗上下文解析。
AJAX 弹窗上下文设置:当交互打开弹窗时,Bricks 会为 AJAX 弹窗暴露上下文控件。Bricks 会尝试自动推断当前上下文;在嵌套查询循环、组件实例、自定义字段 repeater 或更复杂动态数据里,自动上下文可能出错或不可用。当 AJAX 弹窗里的动态数据渲染为空或来自错误对象时,用这些字段:
- Context type:Post、Term 或 User。
- Context ID:用来渲染动态数据的对象 ID(可用
{post_id}、{term_id}或解析为 post/term/user ID 的自定义字段值等动态数据)。
不要用 repeater 行号作为弹窗上下文——AJAX 弹窗上下文期望的是 Bricks 能解析的对象,如 post、term、user。
通过 JavaScript 打开带上下文的 AJAX 弹窗:自 Bricks 1.9.4 起,bricksOpenPopup 接受三个参数——object(弹窗 ID 或元素节点)、timeout(毫秒,供动画/计数器逻辑使用)、additionalParams(AJAX 弹窗上下文数据):
bricksOpenPopup(1190, 0, { popupContextId: 668, popupContextType: 'post' })
bricksOpenPopup(2350, 0, { popupContextId: 39, popupContextType: 'term' })
AJAX 弹窗事件:AJAX 弹窗派发三个 AJAX 专属事件——bricks/ajax/popup/start(请求发出前)、bricks/ajax/popup/end(请求结束后)、bricks/ajax/popup/loaded(内容插入 DOM 后)。每个事件都用 event.detail.popupId 与 event.detail.popupElement。
AJAX 弹窗的打开顺序是:bricks/ajax/popup/start → bricks/ajax/popup/end → bricks/ajax/popup/loaded → bricks/popup/open。非 AJAX 弹窗在打开后直接派发 bricks/popup/open。
Interactions 基础:触发器、动作、目标
一个交互有三部分:
- Trigger(触发器):Bricks 监听的事件,如 click、content loaded、scroll、enter viewport、form success、query AJAX end。
- Action(动作):触发器通过后 Bricks 运行的行为,如 show、hide、toggle class、scroll to、open popup、load more、run JavaScript function。
- Target(目标):受动作影响的元素。根据动作不同,目标可以是同一元素、CSS 选择器,或弹窗模板。
Interactions 运行在前端,不在构建器画布内。用预览或已发布页面来测试时机、选择器、弹窗行为、浏览器存储和 AJAX 流程。
你可以在全局类上定义交互,而不只是单个元素。Bricks 会把全局类交互合并进元素输出,这对可复用按钮、关闭图标、开关等重复行为很有用。
元素触发器
监听在源元素上的触发器:
- Click
- Hover
- Focus
- Blur
- Mouse enter
- Mouse leave
- Enter viewport
- Leave viewport
- Animation end
- Query AJAX loader: Start / End
- Filter Submit: Start / End
- Form Submit、Form Success、Form Error
Click 交互默认调用 event.preventDefault()。自 Bricks 2.0 起,你可以为 click 交互开启 Disable: preventDefault,让被点击元素保留正常的浏览器行为(如跟随链接)。Enter viewport 自 Bricks 2.0 起支持 rootMargin 设置(例如 0px 0px -50% 0px 可让交互在元素到达更具体的视口位置时触发)。Leave viewport 不使用 rootMargin。
浏览器与窗口触发器
不绑定到单个元素事件的触发器:
- Scroll
- Content loaded
- Mouse leave window
Scroll 触发器接受滚动偏移,Bricks 支持像素值、基于文档高度的百分比值、以及基于视口高度的 vh 值。Content loaded 接受延迟如 500ms 或 1s。Run only once 对大多数触发器可用,但 Content loaded 除外。
查询过滤器与 WooCommerce 触发器
开启 Query Filters 后,Bricks 会增加 Filter: Empty / Filter: Not empty 触发器,监听特定 filter 元素 ID(可输入原始 Bricks ID、#id 或 #brxe-id)。支持的过滤器类型:Active filters、Checkbox、Datepicker、Radio、Range、Search、Select。
切换可见性时把 Filter: Empty 与 Filter: Not empty 一起用:如果只在为空时隐藏,通常需要配对的“不为空”交互在下次筛选更新后再次显示它。
启用 WooCommerce 后,Bricks 增加:Added to cart、Adding to cart、Removed from cart、Cart updated、Coupon applied、Coupon removed、Bricks dynamic fragments refreshed、Bricks checkout step changed。其中 dynamic fragments refreshed 与 checkout step changed 监听的是 Bricks 自定义事件(自 Bricks 2.4 起可用)。
动作一览
触发器通过条件后运行的动作包括:
- Show element
- Hide element
- Click element
- Set attribute
- Remove attribute
- Toggle attribute
- Toggle offcanvas
- Load more(Query loop)
- Load more(Image Gallery)
- Start animation
- Scroll to
- JavaScript(Function)
- Open address(Map)
- Close address(Map)
- Clear form
- Checkout step
- Browser storage: Add
- Browser storage: Remove
- Browser storage: Count
Show / Hide 可指向普通元素或弹窗模板:普通元素改内联 display,弹窗则调用弹窗的开关逻辑。Set/Remove/Toggle attribute 作用于所选目标——若属性键是 class,Bricks 通过 classList 增删切换类名,否则设置或移除该属性本身。Click element 对目标元素调用 .click(),适合用一个 UI 控件触发另一个已存在的控件。Clear form 清除 inputs、textareas、selects、checkboxes、radios 与可见文件结果(不清除隐藏 input)。
目标模式
大多数动作用以下目标模式之一:
- Self:在源元素上运行。
- CSS selector:在匹配选择器的每个元素上运行。
- Popup:在所选弹窗模板上运行。
某些动作不使用标准目标控件(有自己的目标字段或无目标),例如 Load more、Browser storage、Toggle offcanvas、Map 动作、Clear form。当弹窗交互在查询循环内时,Bricks 先按“所选弹窗模板 ID + 当前循环项 ID”匹配;找不到循环专属弹窗时,回退到弹窗模板 ID。
Run only once 只运行一次
开启 Run only once 让交互在当前页面生命周期内只运行一次。普通元素事件用一次性事件监听器;文档级事件(form、AJAX、popup、filter、WooCommerce)则在运行后跟踪并移除该交互。Run only once 是页面局部的,不跨页面加载保存;需要持久或会话级规则时用 Browser storage 动作 + 交互条件。
浏览器存储(Browser storage)
浏览器存储动作让交互写入、移除或计数一个键:
- Window storage:存在
window,页面加载后重置。 - Session storage:存在
sessionStorage,浏览器标签页 / 会话结束时通常重置。 - Local storage:存在
localStorage,一直保留直到清除。
存储动作使用与 attribute 动作相同的 Key 字段:Add 把配置值写入键;Remove 移除键;Count 把键当数字读(默认 0)、加一后存回。存储与交互条件搭配特别有用——例如一个交互统计按钮被点了多少次,另一个交互仅在该计数大于 2 时才运行。
JavaScript 函数动作与参数
自 Bricks 1.9.5 起,交互可执行你自己的 JavaScript 函数(仅能执行全局 window 作用域里的函数)。全局定义示例:
window.myHelperFunctions = {}
myHelperFunctions.myCall = () => { console.log('myCall executed') }
myHelperFunctions.nestedFn = {
fn1: () => { console.log('fn1 executed') },
fn2: () => { console.log('fn2 executed') }
}
function toggleMiniCart() {
const run = () => {
document.querySelector('.bricks-woo-toggle').dispatchEvent(new Event('click'))
}
setTimeout(run, 100)
}
在 Function name (JavaScript) 字段里填函数名(不带括号、不带 window.):
myHelperFunctions.myCallmyHelperFunctions.nestedFn.fn1myHelperFunctions.nestedFn.fn2toggleMiniCart
上例里的 run() 因为作用域在 toggleMiniCart() 内部、不在 window 上,所以无法被调用。若目标是匹配多个元素的 CSS 选择器,Bricks 会对每个目标各执行一次该函数。
参数:用 Arguments 中继器给函数传值,%brx% 占位符会传入一个带交互上下文的 Bricks 对象——source(触发交互的源元素)、targets(解析出的目标元素数组)、target(本次调用的当前目标元素):
function playOrPauseVideo(brxParam, postId) {
const target = brxParam?.target || false
if (!target) { return }
const video = target.querySelector('video')
if (!video || !video.play || !video.pause) { return }
if (video.paused) { video.play() } else { video.pause() }
}
交互条件(Interaction conditions)
交互条件让交互仅在浏览器存储匹配规则时运行。条件支持 Window / Session / Local storage,每个条件用以下比较之一检查存储键:Exists、Not exists、==、!=、>=、<=、>、<。数值比较时 Bricks 会把存储值和比较值转成数字,非数值在这些比较里按 0 处理。Relation 控制是全部条件通过(And)还是任一通过(Or)。
动画与弹窗开关
Bricks 用 Animate.css 做交互动画。设动作 Start animation 并选动画类型、时长、可选延迟。当目标是弹窗时,Bricks 把动画应用到 .brx-popup-content;动画名含 In 时打开弹窗,弹窗内容动画含 Out 时在动画结束后关闭弹窗。也就是说,要用动画开/关弹窗时,设交互动作为 Start animation 并选以 In 或 Out 结尾的动画即可,无需再单独监听 animation-end。
Trigger: Animation end(自 Bricks 1.8.4)可在 Start animation 结束后运行另一个交互,用 Target interaction ID 监听某个具体的 Start animation 交互;留空则取同一交互组里上一个 Start animation 交互。也可监听同名 JS 事件:
document.addEventListener('bricks/animation/end/xyyyeh', (event) => {
const element = event.detail.el || false
if (!element) { return }
// Your logic here
})
实战示例
打开页脚按钮的订阅弹窗:
- 创建一个名为 “Newsletter popup” 的 Popup 模板。
- 把弹窗模板条件设为它应当可用的页面,如 Entire website。
- 在页脚加一个按钮。
- 给按钮加一个 Click 交互。
- 目标设为 Popup,选择 Newsletter popup 模板,用 Show element。
这样按钮在弹窗模板渲染到的任何地方都会打开该弹窗。
悬停显示自定义 tooltip:在 Icon 元素旁建一个隐藏的 tooltip 元素(如带 .my-tooltip 类的 Div),给 Icon 加两个交互——Hover / Mouse enter 时显示 .my-tooltip,Mouse leave 时隐藏 .my-tooltip。
做切换按钮:在一个 Div 内放两个 Icon 元素,给外层 Div 加类 .toggle-button,用类似这样的 CSS:
%root% .toggle-close-icon { display: none; }
%root%.is-open .toggle-open-icon { display: none; }
%root%.is-open .toggle-close-icon { display: block; }
给默认图标加 .toggle-open-icon、激活图标加 .toggle-close-icon,然后加交互:默认图标给外层加 is-open 类,激活图标从外层移除 is-open 类。
小结
Popup Builder 把弹窗做成一种可复用、可带条件与断点的模板,并通过 bricksOpenPopup / bricksClosePopup 和 bricks/popup/* 事件暴露给 JavaScript;Interactions 则是驱动这一切的“触发器 → 动作 → 目标”引擎,配合浏览器存储、交互条件与 JavaScript 函数,足以实现退出意图弹窗、查询循环快速预览、表单成功后的弹窗反馈等复杂交互。把可复用的开关 / 关闭行为做成全局类(参见《Bricks 全局类完全指南》),再结合《Bricks CSS Grid 布局与可视化栅格构建器》排布弹窗内布局,能让交互系统既强大又易维护。
延伸阅读
用麦当劳点餐理解 JavaScript Promise(订单承诺类比)
教程:用麦当劳点餐理解 JavaScript Promise(订单承诺类比)——javascript 附完整代码可直接复用,适合外贸独立站与 WordPress 开发者。
tutorial[笔记] JavaScript 模块(ES6 Modules)
教程:[笔记] JavaScript 模块(ES6 Modules)——javascript 附完整代码可直接复用,适合外贸独立站与 WordPress 开发者。
tutorialBricks 查询循环输出 ACF 图片字段的 Alt、Caption、标题数据
教程:Bricks 查询循环输出 ACF 图片字段的 Alt、Caption、标题数据——acf 附完整代码可直接复用,适合外贸独立站与 WordPress 开发者。
tutorialBricks 中输出 ACF Relationship 关联文章的数量
教程:Bricks 中输出 ACF Relationship 关联文章的数量——acf 附完整代码可直接复用,适合外贸独立站与 WordPress 开发者。
