You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用GrapesJS Block Manager实现双标签页滑块面板(各含独立区块)

GrapesJS双标签页区块面板解决方案

核心结论

将.myblocks类应用到两个互斥显示的div不可行。因为GrapesJS的Block Manager在初始化阶段只会绑定第一个匹配该类的元素,切换标签页后新渲染的.myblocks容器不会被自动识别,导致第二个标签页无法加载区块。

推荐方案:使用GrapesJS原生Panel系统构建标签页

GrapesJS内置了面板和命令系统,更适合实现这类标签切换需求,无需依赖DOM显隐逻辑:

1. 初始化配置自定义标签面板

修改GrapesJS初始化代码,添加自定义标签页面板:

const editor = grapesjs.init({
    container: containerId,
    fromElement: true,
    height: height,
    width: width,
    styleManager: { clearProperties: true },
    storageManager: false,
    panels: disablePanel ? { defaults: [] } : {
        defaults: [
            {
                id: 'block-tabs',
                el: '.block-tabs-container',
                buttons: [
                    {
                        id: 'tab-standard',
                        active: true,
                        label: '标准控件',
                        command: 'show-standard-blocks',
                    },
                    {
                        id: 'tab-custom',
                        label: '自定义控件',
                        command: 'show-custom-blocks',
                    },
                ],
            },
        ],
    },
    blockManager: {
        appendTo: '.myblocks',
        blocks: [], // 初始不加载任何区块
    },
});

2. 注册标签切换命令

分别注册两个命令,用于加载对应标签页的区块:

// 定义标准区块数据
const standardBlocks = [
    { id: 'basic-section', label: '基础区块', content: '<section style="padding:20px;"></section>' },
    // 补充更多标准控件...
];

// 定义自定义区块数据
const customBlocks = [
    { id: 'custom-button', label: '自定义按钮', content: '<button class="custom-btn" style="background:#2196F3;color:white;padding:8px 16px;"></button>' },
    // 补充更多自定义控件...
];

// 注册显示标准区块的命令
editor.Commands.add('show-standard-blocks', {
    run(editor) {
        // 清空现有所有区块
        editor.BlockManager.getAll().forEach(block => block.remove());
        // 添加标准区块集合
        standardBlocks.forEach(block => editor.BlockManager.add(block.id, block));
        // 更新标签激活状态
        editor.Panels.getButton('block-tabs', 'tab-standard').set('active', true);
        editor.Panels.getButton('block-tabs', 'tab-custom').set('active', false);
    }
});

// 注册显示自定义区块的命令
editor.Commands.add('show-custom-blocks', {
    run(editor) {
        editor.BlockManager.getAll().forEach(block => block.remove());
        customBlocks.forEach(block => editor.BlockManager.add(block.id, block));
        editor.Panels.getButton('block-tabs', 'tab-standard').set('active', false);
        editor.Panels.getButton('block-tabs', 'tab-custom').set('active', true);
    }
});

3. 调整页面DOM结构

替换原有标签页DOM,只保留面板容器和区块容器:

<div class="block-tabs-container"></div>
<div class="myblocks"></div>

备选方案:手动重新绑定DOM(不推荐)

如果必须保留原有DOM显隐逻辑,需要在标签切换后手动触发Block Manager的容器重新绑定:

// 调整showhide方法
showhide() {
    this.value = !this.value;
    // 等待DOM更新完成后执行
    setTimeout(() => {
        const targetContainer = document.querySelector('.myblocks');
        if (targetContainer && editor) {
            // 重置Block Manager的目标容器
            editor.BlockManager.set('appendTo', targetContainer);
            // 根据当前标签加载对应区块
            editor.BlockManager.getAll().forEach(block => block.remove());
            if (this.value) {
                standardBlocks.forEach(block => editor.BlockManager.add(block.id, block));
            } else {
                customBlocks.forEach(block => editor.BlockManager.add(block.id, block));
            }
        }
    }, 0);
}

这种方式需要处理DOM更新的异步时机,容易出现兼容性问题,稳定性不如原生面板方案。


内容的提问来源于stack exchange,提问作者chetan s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 21:13:14