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

如何基于Editor.js实现文档的部分只读功能?

实现Editor.js的部分只读功能

我目前在使用Editor.js编写文档,想要实现文档的部分只读效果——让指定区块保持可编辑状态,其余区块设置为只读。以下是我当前的Editor.js配置代码:

this.editor = new EditorJS({
    readOnly: this.userRole ? true: false,
    holder: 'editorjs',
    tools: {
        header: Header,   
        image: {
            class: ImageTool,
            config:{
                uploader:{
                    async uploadByFile(file) {
                        // 创建表单数据
                        const formData = new FormData();
                        formData.append('image', file);

                        try {
                            const response = await axios.post('upload_image_file', formData, {
                                headers: {
                                'Content-Type': 'multipart/form-data'
                                }
                            });
                            console.log("🚀 ~ uploadByFile ~ response.data:", response.data)

                            return {
                                success: 1,
                                file: {
                                url: response.data.file.url
                                }
                            };
                        } catch (error) {
                        console.error('图片上传错误:', error);
                            return {
                                success: 0,
                                error: '图片上传失败'
                            };
                        }
                    },             
                    async uploadByUrl(url) {
                        try {
                        const response = await axios.post('upload_image_url', {
                            url: url
                        });

                        if (response.data.success && response.data.file && response.data.file.url) {
                            return {
                            success: 1,
                            file: {
                                url: response.data.file.url
                            }
                            };
                        } else {
                            return {
                            success: 0,
                            error: '图片上传失败'
                            };
                        }
                        } catch (error) {
                        console.error('图片上传错误:', error);
                        return {
                            success: 0,
                            error: '图片上传失败'
                        };
                        }
                    }                                           
                }
            }
        },
        textVariant: TextVariantTune,
        checklist: {
            class: Checklist,
            inlineToolbar: true,
        },   
        list: {
            class: NestedList,
            inlineToolbar: true,
            config: {
                defaultStyle: 'unordered'
            },
        },   
        embed: Embed,    
        Marker: {
            class: Marker,
            shortcut: 'CMD+SHIFT+M',
        },
        table: {
            class: Table,
            inlineToolbar: true,
            config: {
                rows: 2,
                cols: 3,
            },
        },   
        warning: {
            class: Warning,
            inlineToolbar: true,
            shortcut: 'CMD+SHIFT+W',
            config: {
                titlePlaceholder: '标题',
                messagePlaceholder: '内容',
            },
        },    
        translator: {
            class: Translate,
            config: {
                endpoint: 'http://localhost:5000/translate?text=',
            }
        },     
        attaches: {
            class: AttachesTool,
            config: {
                endpoint: 'http://localhost:8008/uploadFile'
            }
        }                                                                 
    },
    tunes: ['textVariant'],
    data:this.contractData
});

解决方案

Editor.js本身没有原生的“部分区块只读”配置项,但可以通过以下几种方式实现需求:

1. 基于区块属性批量设置只读状态

初始化编辑器时不设置全局readOnly,等编辑器加载完成后,遍历所有区块,根据预设条件(比如区块类型、ID或自定义标记)控制只读状态:

// 编辑器初始化完成后执行
this.editor.isReady.then(() => {
    const blocks = this.editor.blocks.getBlocks();
    
    blocks.forEach(block => {
        // 示例:将header类型区块设为只读,其余保持可编辑
        const isReadOnly = block.name === 'header';
        
        // 禁用/启用内容编辑
        block.holder.contentEditable = !isReadOnly;
        
        // 移除/保留区块操作按钮(删除、拖拽等)
        const actionsBar = block.holder.querySelector('.ce-block__actions');
        if (isReadOnly) {
            actionsBar?.remove();
        }
    });
});

2. 自定义工具类实现专属只读逻辑

针对特定工具(比如图片、检查表),可以继承原工具类,添加只读判断逻辑,禁用交互元素:

以ImageTool为例,自定义工具类:

class CustomImageTool extends ImageTool {
    render() {
        const element = super.render();
        // 根据区块数据或全局规则判断是否只读
        if (this.data.isReadOnly) {
            // 隐藏上传按钮、URL输入框等交互元素
            element.querySelector('.cdx-image-tool__input')?.remove();
            element.querySelector('.cdx-image-tool__button')?.remove();
        }
        return element;
    }
}

然后在Editor配置中替换原工具:

image: {
    class: CustomImageTool,
    // 原有config配置保持不变
}

3. 动态切换区块只读状态

如果需要在编辑过程中随时切换区块状态,可以封装一个工具方法:

function toggleBlockReadOnly(blockId, isReadOnly) {
    const block = this.editor.blocks.getBlockById(blockId);
    if (!block) return;
    
    block.holder.contentEditable = !isReadOnly;
    const actionsBar = block.holder.querySelector('.ce-block__actions');
    
    if (isReadOnly) {
        actionsBar?.remove();
    } else {
        // 若需要恢复操作按钮,可调用Editor.js内部方法重新渲染
        block.renderActions();
    }
}

注意事项

  • 上述方法依赖Editor.js内部API,升级版本时需注意兼容性
  • 对于内嵌工具栏(inlineToolbar),可通过添加CSS隐藏:.ce-inline-toolbar { display: none !important; }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 06:12:08