11 KiB
Bricks UI Framework - Popup 组件技术文档
概述
bricks.Popup 是基于 bricks.VBox 的弹窗组件,用于创建可浮动、可移动、可调整大小的模态或非模态对话框。它支持自动打开/关闭、点击外部区域自动关闭、内容动态加载等功能。
此外,框架还提供了两个扩展类:
bricks.PopupWindow:带标题栏和控制按钮(最小化、全屏、关闭)的窗口式弹窗。bricks.WindowsPanel:用于管理多个最小化的窗口列表面板。
该组件适用于构建现代化 Web 应用中的对话框、提示框、应用窗口等交互界面。
全局命名空间初始化
var bricks = window.bricks || {};
确保 bricks 命名空间存在,避免覆盖已有对象。
默认配置方法
bricks.get_popup_default_options()
返回一个包含默认选项的对象,供 Popup 使用。
返回值
{
timeout: 0,
archor: 'cc',
auto_open: true,
auto_dismiss: true,
auto_destroy: true,
movable: true,
resizable: false,
modal: true
}
| 参数 | 类型 | 描述 |
|---|---|---|
timeout |
Number | 自动关闭延迟时间(秒),设为 0 表示不自动关闭 |
archor |
String | 定位锚点,取值见下表 |
auto_open |
Boolean | 是否在实例化后自动打开弹窗 |
auto_dismiss |
Boolean | 是否允许点击外部区域关闭弹窗 |
auto_destroy |
Boolean | 关闭后是否自动销毁组件 |
movable |
Boolean | 是否可拖动 |
resizable |
Boolean | 是否可调整大小 |
modal |
Boolean | 是否为模态(遮罩其他控件) |
archor取值说明
支持九宫格定位:
'tl','tc','tr','cl','cc','cr','bl','bc','br'
分别表示:左上、中上、右上、左中、居中、右中、左下、中下、右下
核心类:bricks.Popup
继承自 bricks.VBox,提供完整的弹窗功能。
构造函数:constructor(opts)
参数
opts(Object): 配置选项,合并默认配置使用。
内部属性初始化
| 属性 | 类型 | 初始值 | 说明 |
|---|---|---|---|
no_opened |
Boolean | true |
是否首次打开 |
auto_task |
Task | null |
超时任务句柄 |
issub |
Boolean | false |
是否依附于某个控件显示 |
opened |
Boolean | false |
当前是否已打开 |
content_box |
VBox | 实例 | 内容容器 |
content_w |
Widget | content_box |
内容承载部件 |
moving_w |
Widget | this |
可拖动目标(默认整个弹窗) |
target_w |
Widget | bricks.Body |
目标绑定控件 |
moving_status |
Boolean | false |
拖拽状态标志 |
resize_status |
Boolean | false |
缩放状态标志 |
初始化流程
- 设置 CSS 类名为
popup - 将自身置于顶层(z-index)
- 创建内容容器并添加到内部
- 绑定点击外部关闭事件(若启用
auto_dismiss) - 启用拖动(
movable)与缩放(resizable) - 默认隐藏(
display: none) - 添加至
Body容器 - 绑定点击以提升层级
- 若
auto_open === true,调用open() - 若有
content,监听opened事件加载内容
方法详解
load_content() → Promise<void>
异步加载配置中的 content 并渲染到内容区。
async load_content(){
var w = await bricks.widgetBuild(this.content, this);
if (w){
this.set_dismiss_events(w);
this.content_w.clear_widgets();
this.content_w.add_widget(w);
}
}
⚠️ 依赖
bricks.widgetBuild()动态构建子控件树。
set_dismiss_events(widget)
为指定控件绑定关闭事件。
this.dismiss_events.forEach(ename => {
w.bind(ename, this.destroy.bind(this));
});
示例:
dismiss_events: ['ok', 'cancel']会绑定这些事件触发销毁。
bring_to_top()
将当前弹窗置顶(最高 z-index),更新全局 toppopup 引用。
this.zindex = bricks.app.new_zindex();
this.set_style('zIndex', this.zindex);
bricks.app.toppopup = this;
popup_from_widget(from_w)
从指定控件位置智能定位弹窗(避开屏幕边缘)。
算法逻辑
- 计算源控件中心坐标
(ox, oy) - 若源在左侧,则弹窗出现在右侧;否则出现在左侧
- 若源在上方,则弹窗出现在下方;否则出现在上方
- 边界检测防止溢出屏幕
适用于 Tooltip 或 Context Menu 场景。
setup_resizable()
启用可缩放功能,在右下角添加 SVG 缩放手柄。
子组件
resizable_w: SVG 图标(右下三角)
事件绑定
mousedown→resize_start_posmousemove→resizingmouseup→stop_resizing
resize_start_pos(e)
记录初始尺寸和鼠标位置,开始缩放。
this.s_width = rect.width;
this.s_height = rect.height;
this.s_offsetX = e.clientX;
this.s_offsetY = e.clientY;
resizing(e)
实时调整宽度和高度。
cx = this.s_width + e.clientX - this.s_offsetX;
cy = this.s_height + e.clientY - this.s_offsetY;
this.set_style('width', cx + 'px');
this.set_style('height', cy + 'px');
stop_resizing(e)
结束缩放操作,解绑全局事件。
this.resize_status = false;
bricks.Body.unbind('mousemove', this.resizing.bind(this));
bricks.Body.unbind('mouseup', this.stop_resizing.bind(this));
positify_tl()
根据 archor 和屏幕尺寸计算并设置弹窗位置。
尺寸解析优先级
cwidth/cheight(字符单位 × 字符大小)width/height(百分比或 px)- 默认占屏 80%
锚点布局规则
| 第一位(垂直) | 第二位(水平) |
|---|---|
t: 顶部对齐 |
l: 左对齐 |
c: 居中 |
c: 居中 |
b: 底部对齐 |
r: 右对齐 |
返回
{ top, left }像素坐标。
setup_movable()
启用拖动功能,绑定 mousedown 和 touchstart。
rec_start_pos(e)
记录拖动起点偏移量,并绑定移动与释放事件。
this.offsetX = e.clientX - rect.left;
this.offsetY = e.clientY - rect.top;
moving(e)
实时更新位置。
cx = e.clientX - this.offsetX;
cy = e.clientY - this.offsetY;
this.set_style('left', cx + 'px');
this.set_style('top', cy + 'px');
stop_moving(e)
停止拖动,解绑所有相关事件。
click_outside(event)
点击弹窗外区域时关闭弹窗(仅当 auto_dismiss 为 true 时生效)。
if (event.target != this.dom_element) this.dismiss();
open()
打开弹窗。
流程
- 若无父节点,加入
app根容器 - 若是首次打开:
- 设置目标控件(
widget参数) - 执行定位
positify_tl()
- 设置目标控件(
- 显示元素(
display: block) - 触发
opened事件 - 设置超时关闭任务(如需)
- 若为模态,则禁用目标控件
- 提升至顶层
dismiss()
关闭弹窗。
流程
- 若为模态,恢复目标控件可用状态
- 清除超时任务
- 隐藏元素(
display: none) - 触发
dismissed事件 - 若
auto_destroy === true,执行destroy()
destroy()
彻底销毁组件。
if (this.opened) this.dismiss();
if (this.parent) {
this.parent.remove_widget(this);
this.parent = null;
}
add_widget(w, i)
向内容区域添加控件,并自动绑定关闭事件。
若
auto_open为true,则立即打开弹窗。
remove_widget(w) / clear_widgets()
代理调用 content_w 的对应方法。
扩展类:bricks.PopupWindow
继承自 Popup,模拟操作系统窗口,带有标题栏和控制按钮。
构造函数特点
opts.movable = true;
opts.resizable = true;
opts.auto_open = false; // 手动控制打开时机
特有属性
| 属性 | 说明 |
|---|---|
title_bar |
标题栏容器(HBox) |
tb_w |
控制按钮栏(IconBar) |
content_w |
主内容区(Layout) |
title_w |
标题文本显示控件 |
内部结构
- 标题栏 (
titlebar)- 图标(SVG)
- 控制按钮组(删除、最小化、全屏)
- 标题文本
- 填充层 (
Filler)- 包含主内容区
- 内容区 (
Layout)- 支持 Flex 布局
控制按钮功能
| 按钮 | 功能 |
|---|---|
delete |
调用 destroy() 销毁窗口 |
minimize |
调用 win_minimize() 最小化 |
fullscreen |
进入全屏模式 |
win_minimize()
关闭窗口并将自身推入 bricks.app.mwins 数组,供后续恢复。
this.dismiss();
if (!this.auto_destroy) {
bricks.app.mwins.push(this);
}
set_title(txt)
动态修改窗口标题。
this.title_w.set_text(txt);
工具类:bricks.WindowsPanel
用于展示所有最小化的窗口列表,点击可恢复。
构造函数行为
- 固定宽高为
80% - 自动关闭、销毁
- 不自动打开
数据绑定结构
使用 Cols 组件渲染表格:
{
"total": 3,
"rows": [
{ "title": "Settings", "url": "...", "pos": 0 },
...
]
}
每行包含图标、标题,点击触发 del_window()。
del_window(event)
恢复指定位置的窗口并从列表中移除。
var pos = event.params.pos;
var w = bricks.app.mwins[pos];
w.open(); // 恢复显示
bricks.app.mwins.splice(pos, 1); // 删除记录
this.dismiss(); // 关闭面板
工厂注册
bricks.Factory.register('Popup', bricks.Popup);
bricks.Factory.register('PopupWindow', bricks.PopupWindow);
支持通过字符串类型动态创建组件实例。
静态辅助函数
bricks.get_popupwindow_default_options()
返回专用于 PopupWindow 的默认配置,与普通 Popup 的区别在于:
+ resizable: true
其余同 get_popup_default_options()。
使用示例
创建简单弹窗
let popup = new bricks.Popup({
content: {
widgettype: 'Text',
options: { text: 'Hello World!' }
},
archor: 'cc',
timeout: 3000
});
创建应用窗口
let win = new bricks.PopupWindow({
title: '用户设置',
icon: '/icons/settings.svg',
content: { ... },
auto_open: true
});
显示窗口管理器
let panel = new bricks.WindowsPanel();
panel.open();
注意事项
- 事件作用域问题:大量使用
.bind(this),注意性能影响。 - 内存泄漏风险:未正确解绑事件可能导致残留监听器。
- 触摸设备兼容性:支持
touchstart/move/end,但需测试跨平台表现。 - z-index 管理:依赖
bricks.app.new_zindex(),需保证唯一递增。 - 异步内容加载:
load_content()为异步,注意加载顺序。
总结
bricks.Popup 系列组件提供了强大而灵活的弹窗系统,具备以下核心能力:
✅ 模态/非模态切换
✅ 自动定位与边界适配
✅ 拖拽移动 & 缩放
✅ 外部点击关闭
✅ 超时自动关闭
✅ 内容动态加载
✅ 窗口最小化管理
适合构建复杂的桌面风格 Web 应用界面。
文档版本:v1.0
最后更新:2025-04-05