开源好用的所见即所得(WYSIWYG)编辑器:Editor.js

news2024/12/25 12:33:42

文章目录

  • 特点
    • 基于区块
    • 干净的数据
  • 界面与交互
    • 插件
    • 标题和文本
    • 图片
    • 列表
    • Todo
    • 表格
  • 使用
    • 安装
    • 创建编辑器实例
    • 配置工具
    • 本地化
    • 自定义样式

今天介绍一个开源好用的Web所见即所得(WYSIWYG)编辑器: Editor.js

Editor.js 是一个基于 Web 的所见即所得富文本编辑器,它由CodeX团队开发。源代码托管于Github:https://github.com/codex-team/editor.js

特点

它有两个显著的特点,一个是基于区块(block-styled)的编辑模式,另一个是可以输出干净的数据。

基于区块

基于区块官网是这样解释的:

Editor.js工作区由单独的区块组成:段落、标题、图像、列表、引号等。它们中的每一个都是由 Plugin 提供的独立元素(或更复杂的结构)并由 Editor’s Core 连结。

干净的数据

Editor.js 输出干净的json数据而不是 HTML 标记,虽然对浏览器来说,HTML 是更直观的,但对服务器来说,json更精简更关注内容本身,易于重复使用,存储和传输。

对于控件本身也更易于实现,比如在文本“加粗”和“常规”来回切换,基于json的更改一个属性,总要比基于HTML反复添加和删除标记更简单吧?

界面与交互

在编辑区域,Editor.js提供了区块工具栏(Block Tools),内联工具栏(Inline Tools)和区块编辑栏(Block Tunes)

在这里插入图片描述

他们分别通过 加号 + 按钮,选中区块内容和菜单(六个点和尚按钮)来访问🤓

在这里插入图片描述

插件

每个区块都通过插件提供支持,官方提供了常用的插件,当然也可以自己写插件。

官方提供的插件如下图,在sample中,都以cdn方式引入了这些插件,也可以通过npm安装。

在这里插入图片描述

标题和文本

在这里插入图片描述

序列化后的数据如下图所示,

{
    "id" : "zcKCF1S7X8",
    "type" : "header",
    "data" : {
        "text" : "Editor.js",
        "level" : 1
    }
},
{
    "id" : "b6ji-DvaKb",
    "type" : "paragraph",
    "data" : {
        "text" : "支持文本,标题,列表,代办,表格,图片,链接,代码片段,引用片段等等"
    }
},

在这里插入图片描述

{
    "id" : "SSBSguGvP7",
    "type" : "list",
    "data" : {
        "style" : "ordered",
        "items" : [
            {
                "content" : "支持普通文本,<i>斜体文本</i>,<b>加粗</b>",
                "items" : []
            },
            {
                "content" : "支持<mark class=\"cdx-marker\">文本高亮</mark>、<a href=\"https://baidu.com\">文本链接</a>、<code class=\"inline-code\">代码片段</code><mark class=\"cdx-marker\"></mark>",
                "items" : []
            }
        ]
    }
},

图片

图片支持Base64编码,和url两种方式上传图片

在这里插入图片描述

{
    "id" : "VYsWoLL7yj",
    "type" : "image",
    "data" : {
        "url" : "data:image/png;base64, ...",
        "caption" : "codex2x.png",
        "withBorder" : false,
        "withBackground" : false,
        "stretched" : false
    }
}

列表

支持有序和无序列表,列表支持嵌套

在这里插入图片描述

无序列表:

{
            "id" : "i_cVQxn3Tb",
            "type" : "list",
            "data" : {
                "style" : "unordered",
                "items" : [
                    {
                        "content" : " 香蕉🍌",
                        "items" : []
                    },
                    {
                        "content" : " 苹果🍎",
                        "items" : []
                    },
                    {
                        "content" : " 葡萄🍇  ",
                        "items" : []
                    }
                ]
            }
        },

有序列表:

        {
            "id" : "nOTdryosj2",
            "type" : "list",
            "data" : {
                "style" : "ordered",
                "items" : [
                    {
                        "content" : "洗手心",
                        "items" : []
                    },
                    {
                        "content" : "搓手背",
                        "items" : []
                    },
                    {
                        "content" : "洗指缝",
                        "items" : []
                    }
                ]
            }
        },

嵌套列表:

        {
            "id" : "LJjzlmGa-3",
            "type" : "list",
            "data" : {
                "style" : "unordered",
                "items" : [
                    {
                        "content" : "序章",
                        "items" : []
                    },
                    {
                        "content" : "第一章",
                        "items" : [
                            {
                                "content" : "第一节",
                                "items" : [
                                    {
                                        "content" : "a)",
                                        "items" : []
                                    },
                                    {
                                        "content" : "b)",
                                        "items" : []
                                    },
                                    {
                                        "content" : "c)",
                                        "items" : []
                                    }
                                ]
                            },
                            {
                                "content" : "第二节",
                                "items" : []
                            }
                        ]
                    }
                ]
            }
        },

Todo

在这里插入图片描述

{
            "id" : "Hitrs4RqXw",
            "type" : "checklist",
            "data" : {
                "items" : [
                    {
                        "text" : "满意😊",
                        "checked" : true
                    },
                    {
                        "text" : "一般😐",
                        "checked" : false
                    },
                    {
                        "text" : "不满意☹️",
                        "checked" : false
                    }
                ]
            }
        },

表格

在这里插入图片描述

不代表头:

{
    "id" : "xPAQ6AkUiK",
    "type" : "paragraph",
    "data" : {
        "text" : "<b>不带表头</b>"
    }
},
{
    "id" : "_MMoOqlgXs",
    "type" : "table",
    "data" : {
        "withHeadings" : false,
        "content" : [
            [
                "<b>重要紧急</b>",
                "<b>重要不紧急</b>"
            ],
            [
                "吃饭睡觉",
                "订生日蛋糕"
            ],
            [
                "<b>不重要但紧急</b>",
                "<b>不重要不紧急</b>"
            ],
            [
                "上班前定好闹钟",
                "总结这一周的工作"
            ]
        ]
    }
},

带表头:

{
    "id" : "fvfQSljMK8",
    "type" : "table",
    "data" : {
        "withHeadings" : true,
        "content" : [
            [
                "星期一",
                "星期二",
                "星期三",
                "星期四",
                "星期五"
            ],
            [
                "a",
                "b",
                "c",
                "d",
                "e"
            ]
        ]
    }
},

使用

安装

页面中引用Editor.js Core库,可通过npm安装。也可以编译项目,然后引入编译后的js文件。

yarn add @editorjs/editorjs

<script src="lib/editorjs/editorjs.umd.js"></script>

创建编辑器实例

在页面创建编辑器


import EditorJS from '@editorjs/editorjs';


const editor = new EditorJS({
  /**
   * Id of Element that should contain Editor instance
   */
  holder: 'editorjs'
});

这是一个最小化的示例。你会发现没有那些默认的工具。因此需要在配置中指定工具。

配置工具

可以通过传入配置对象创建编辑器实例。以下是示例

在这里插入图片描述

holder指定编辑器的容器元素。


window.editor = new window.EditorJS({
    /**
        * Wrapper of Editor
        */
    holder: 'editorjs',

配置工具

配置完成后,区块工具栏将呈现一个较为完整的工具列表。

    /**
        * Tools list
        */
    tools: {
        paragraph: {
            config: {
                placeholder: "Enter something"
            }
        },

        header: {
            class: Header,
            inlineToolbar: ['link'],
            config: {
                placeholder: 'Header'
            },
            shortcut: 'CMD+SHIFT+H'
        },

        /**
            * Or pass class directly without any configuration
            */
        image: ImageTool,

        list: {
            class: NestedList,
            inlineToolbar: true,
            shortcut: 'CMD+SHIFT+L'
        },

        checklist: {
            class: Checklist,
            inlineToolbar: true,
        },

        quote: {
            class: Quote,
            inlineToolbar: true,
            config: {
                quotePlaceholder: 'Enter a quote',
                captionPlaceholder: 'Quote\'s author',
            },
            shortcut: 'CMD+SHIFT+O'
        },


        marker: {
            class: Marker,
            shortcut: 'CMD+SHIFT+M'
        },

        code: {
            class: CodeTool,
            shortcut: 'CMD+SHIFT+C'
        },

        delimiter: Delimiter,

        inlineCode: {
            class: InlineCode,
            shortcut: 'CMD+SHIFT+C'
        },

        linkTool: LinkTool,

        embed: Embed,

        table: {
            class: Table,
            inlineToolbar: true,
            shortcut: 'CMD+ALT+T'
        },

    },
    

    /**
        * Initial Editor data
        */
    data: obj,
    onReady: function () {
        saveButton.click();
    },
});

本地化

可以通过传入i18n配置对象来设置编辑器的本地化。以下是一个较为完整的中文化示例:


i18n: {
    messages: {
        "ui": {
            "blockTunes": {
                "toggler": {
                    "Click to tune": "点击转换",
                    "or drag to move": "拖动调整"
                },
            },
            "inlineToolbar": {
                "converter": {
                    "Convert to": "转换成"
                }
            },
            "toolbar": {
                "toolbox": {
                    "Add": "添加",
                    "Filter": "过滤",
                    "Nothing found": "无内容"
                },
                "popover": {
                    "Filter": "过滤",
                    "Nothing found": "无内容"
                }
            }
        },
        "toolNames": {
            "Text": "段落",
            "Heading": "标题",
            "List": "列表",
            "Warning": "警告",
            "Checklist": "清单",
            "Quote": "引用",
            "Code": "代码",
            "Delimiter": "分割线",
            "Raw HTML": "HTML片段",
            "Table": "表格",
            "Link": "链接",
            "Marker": "突出显示",
            "Bold": "加粗",
            "Italic": "倾斜",
            "InlineCode": "代码片段",
            "Image": "图片"
        },
        "tools": {
            "link": {
                "Add a link": "添加链接"
            },
            "stub": {
                'The block can not be displayed correctly.': '该模块不能放置在这里'
            },
            "image": {
                "Caption": "图片说明",
                "Select an Image": "选择图片",
                "With border": "添加边框",
                "Stretch image": "拉伸图像",
                "With background": "添加背景",
            },
            "code": {
                "Enter a code": "输入代码",
            },
            "linkTool": {
                "Link": "请输入链接地址",
                "Couldn't fetch the link data": "获取链接数据失败",
                "Couldn't get this link data, try the other one": "该链接不能访问,请修改",
                "Wrong response format from the server": "错误响应",
            },
            "header": {
                "Header": "标题",
                "Heading 2": "二级标题",
                "Heading 3": "三级标题",
                "Heading 4": "四级标题",
                "Heading 5": "五级标题",
            },
            "paragraph": {
                "Enter something": "请输入笔记内容",
            },
            "list": {
                "Ordered": "有序列表",
                "Unordered": "无序列表",
            },
            "table": {
                "Heading": "标题",
                "Add column to left": "在左侧插入列",
                "Add column to right": "在右侧插入列",
                "Delete column": "删除列",
                "Add row above": "在上方插入行",
                "Add row below": "在下方插入行",
                "Delete row": "删除行",
                "With headings": "有标题",
                "Without headings": "无标题",
            },
            "quote": {
                "Align Left": "左对齐",
                "Align Center": "居中对齐",
            }
        },
        "blockTunes": {
            "delete": {
                "Delete": "删除",
                'Click to delete': "点击删除"
            },
            "moveUp": {
                "Move up": "向上移"
            },
            "moveDown": {
                "Move down": "向下移"
            },
            "filter": {
                "Filter": "过滤"
            }
        },
    }
}

自定义样式

varaiables.css中包含了大部分的样式变量,更改这些变量可以实现自定义样式。

在这里插入图片描述

如通过重写 .root样式选择器可以实现自定义的背景色, 重写.ce-popover 改变弹出框样式等。

:root {
    --color-bg-main: #F0F0F0;
    --color-border-light: #E8E8EB;
    --color-text-main: #000;
    --selectionColor: #e1f2ff;
}


.ce-popover {
    --border-radius: 6px;
    --width: 200px;
    --max-height: 270px;
    --padding: 6px;
    --offset-from-target: 8px;
    --color-border: #e8e8eb;
    --color-shadow: rgba(13,20,33,0.13);
    --color-background: white;
    --color-text-primary: black;
    --color-text-secondary: #707684;
    --color-border-icon: rgb(201 201 204 / 48%);
    --color-border-icon-disabled: #EFF0F1;
    --color-text-icon-active: #388AE5;
    --color-background-icon-active: rgba(56, 138, 229, 0.1);
    --color-background-item-focus: rgba(34, 186, 255, 0.08);
    --color-shadow-item-focus: rgba(7, 161, 227, 0.08);
    --color-background-item-hover: #eff2f5;
    --color-background-item-confirm: #E24A4A;
    --color-background-item-confirm-hover: #CE4343;
}
.dark-mode {
  --color-border-light: rgba(255, 255, 255,.08);
  --color-bg-main: #1c1e24;
  --color-text-main: #737886;
}

在这里插入图片描述

在这里插入图片描述
– 完 –

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1509795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FTP,SFTP,FTPS,SSL,TSL简介,区别,联系,使用场景说明

文章目录 简介FTPFTPSSFTP加密场景选择FTPS还是SFTPFTP、SFTP、FTPS区别、联系和具体使用场景如何使用FTP、SFTP和FTPSSSLTLSSSL和TLS区别和联系&#xff0c;以及使用场景SSL和TLS技术上的区别一些问题隐式的TLS&#xff08;FTPS/SSL&#xff09;或者显式的TLS&#xff08;FTPS…

【Datawhale学习笔记】从大模型到AgentScope

从大模型到AgentScope AgentScope是一款全新的Multi-Agent框架&#xff0c;专为应用开发者打造&#xff0c;旨在提供高易用、高可靠的编程体验&#xff01; 高易用&#xff1a;AgentScope支持纯Python编程&#xff0c;提供多种语法工具实现灵活的应用流程编排&#xff0c;内置…

蓝桥·算法双周赛|第七场分级赛——小白入门赛

&#x1f525;博客介绍&#xff1a; 27dCnc &#x1f3a5;系列专栏&#xff1a; <<数据结构与算法>> << 算法入门>> << C项目>> &#x1f3a5; 当前专栏: << 算法入门>> 专题 : 数据结构帮助小白快速入门算法 &#x1f4…

【全志H616】1 --用orangepi控制硬件

【全志H616】1 --用orangepi控制硬件 本文介绍了如歌用orangepi 控制蜂鸣器&超声波模块&#xff0c;通过键盘输入1、2、3、4来控制转动角度舵机模块&#xff1b;同时还介绍了利用全志如何配置定时器&#xff1b;以及查看H616引脚状态的命令等… 超声波模块和舵机模块的讲解…

Python递归函数你用对了吗?

1.递归函数 递归函数&#xff1a;函数自己调用自己 2.需求 使用函数的方式&#xff0c;计算数字n的阶乘 # 5&#xff01; """ 5! 1 * 2 * 3 * 4 * 5 4! 1 * 2 * 3 * 4 3! 1 * 2 * 3 2! 1 * 2 1! 1综上可以总结出&#xff1a;n! n * (n - 1) "&qu…

案例分析篇02:软件架构设计考点之特定领域软件架构、架构评估、架构视图(2024年软考高级系统架构设计师冲刺知识点总结)

专栏系列文章推荐: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-…

鼠标在QTreeView、QTableView、QTableWidget项上移动,背景色改变

目录 1. 前言 2. 需求 3. 功能实现 3.1. 代码实现 3.2. 功能讲解 4. 附录 1. 前言 本博文用到了Qt的model/view framework框架,如果对Qt的“模型/视图/委托”框架不懂&#xff0c;本博文很难读懂。如果不懂这方面的知识&#xff0c;请在Qt Assistant 中输入Model/View…

[iOS]高版本MacOS运行低版本Xcode

Xcode 版本支持文档 目的&#xff1a; 在MacOS Sonoma 系统上安装 Xcode14.3.1 第一步 先在Xcode下载一个Xcode14.3.1的压缩包 第二步 本地解压Xcode&#xff0c;将外层目录名变更为Xcode_14.3.1&#xff0c;将文件拷贝到 /Applications目录下。 第三步 变更xcode-sel…

Docker基础教程 - 12 常用容器部署-Nginx

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 12 常用容器部署-Nginx 下面介绍一下常用容器的部署。可以先简单了解下&#xff0c;用到再来详细查看。 在 Docker 中部署 Nginx&#xff0c;并通过挂载方式将 Nginx 的配置文件和站点目录挂…

leecode算法二

滑动窗口/双指针 滑动窗口 得到K个黑块的最少涂色次数 滑动窗口法 方法一 方法二 水果成篮 二叉树 概念 中序遍历 前序遍历和后序遍历无非就是把result.add房价加在前面和后面。 层序遍历 广度优先算法 深度优先算法 线段树 我的日程安排表II

Day36:安全开发-JavaEE应用第三方组件Log4j日志FastJson序列化JNDI注入

目录 Java-项目管理-工具配置 Java-三方组件-Log4J&JNDI Java-三方组件-FastJson&反射 思维导图 Java知识点&#xff1a; 功能&#xff1a;数据库操作&#xff0c;文件操作&#xff0c;序列化数据&#xff0c;身份验证&#xff0c;框架开发&#xff0c;第三方库使用…

[Unity3D]--更换天空盒子

我们原来的天空盒子是这样的。 感觉不是特别满意&#xff0c;想换一个更好看的。 去资源商店找个好看的 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 例如这个 然后在Window>Rendering>Lighting里的环境选项里更换材质 更换&#xff1a; ​ …

SpringBoot注解--08--注解@JsonInclude

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 JsonInclude注解是jackSon中最常用的注解之一&#xff0c;是为实体类在接口序列化返回值时增加规则的注解 1.JsonInclude用法2.JsonInclude注解中的规则有 案例需求…

卷积神经网络CNN(一篇文章 理解)

目录 一、引言 二、CNN算法概述 1 卷积层 2 池化层 3 全连接层 三、CNN算法原理 1 前向传播 2 反向传播 四、CNN算法应用 1 图像分类 2 目标检测 3 人脸识别 六、CNN的优缺点 优点&#xff1a; 1 特征提取能力强 2 平移不变性 3 参数共享 4 层次化表示 缺点…

机器学习-04-分类算法-01决策树案例

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中分类算法&#xff0c;本篇为分类算法开篇与决策树部分。 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程…

一次因PageHelper引起的多线程复用问题的排查和解决方案

目录导航 导读01.Problem Description02.Problem inspection Steps1. Code Review2. Log Check and Prove 03.Analysis Steps1. How to use PageHelpera. Github Official Document Linkb. Analysis Source Code of PageHelper 2. How to solve the problem 导读 本文不仅对遇…

作用域链的理解(超级详细)

文章目录 一、作用域全局作用域函数作用域块级作用域 二、词法作用域三、作用域链 一、作用域 作用域&#xff0c;即变量&#xff08;变量作用域又称上下文&#xff09;和函数生效&#xff08;能被访问&#xff09;的区域或集合 换句话说&#xff0c;作用域决定了代码区块中变…

狂飙Linux平台,PostgreSQL16部署大全

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

生成式 AI:使用 Pytorch 通过 GAN 生成合成数据

导 读 生成对抗网络&#xff08;GAN&#xff09;因其生成图像的能力而变得非常受欢迎&#xff0c;而语言模型&#xff08;例如 ChatGPT&#xff09;在各个领域的使用也越来越多。这些 GAN 模型可以说是人工智能/机器学习目前主流的原因&#xff1b; 因为它向每个人&#xff0…

vue+elementUI用户修改密码的前端验证

用户登录后修改密码&#xff0c;密码需要一定的验证规则。旧密码后端验证是否正确&#xff1b;前端验证新密码的规范性&#xff0c;新密码规范为&#xff1a;6-16位&#xff0c;至少含数字/字母/特殊字符中的两种&#xff1b;确认密码只需要验证与新密码是否一致&#xff1b; 弹…