如何基于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
相关产品推荐
相关产品推荐

