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

文章目录

  • 特点
    • 基于区块
    • 干净的数据
  • 界面与交互
    • 插件
    • 标题和文本
    • 图片
    • 列表
    • 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;
}

在这里插入图片描述

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【毕设级项目】基于AI技术的多功能消防机器人(完整工程资料源码)

基于AI技术的多功能消防机器人演示效果 竞赛-基于AI技术的多功能消防机器人视频演示 前言 随着“自动化、智能化”成为数字时代发展的关键词&#xff0c;机器人逐步成为社会经济发展的重要主体之一&#xff0c;“机器换人”成为发展的全新趋势和时代潮流。在可预见的将来&#…

鸿蒙App基础

基础说明 .1、应用模型 .1.1、构成要素 应用组件 应用组件是应用的基本组成单位&#xff0c;是应用的运行入口。用户启动、使用和退出应用过程中&#xff0c;应用组件会在不同的状态间切换&#xff0c;这些状态称为应用组件的生命周期。应用组件提供生命周期的回调函数&…

如何提高API接口的性能和设计安全可靠的API

如何提高API接口的性能 下图显示了提高 API 性能的 5 种常见技巧。 分页 这是在结果集较大时常用的优化方法。结果会以流式方式传回客户端&#xff0c;以提高服务响应速度。 异步日志 同步日志每次调用都要处理磁盘&#xff0c;会降低系统速度。异步日志会先将日志发送到无…

力扣226.翻转二叉树(二叉树的先序遍历)

文章目录 题目描述思路复杂度Code 题目描述 思路 利用二叉树的先序遍历&#xff0c;每次递归遍历时将当前节点的左右子节点交换即可 复杂度 时间复杂度: O ( n ) O(n) O(n)&#xff1b;其中 n n n为树节点的个数 空间复杂度: O ( h e i g h ) O(heigh) O(heigh)&#xff1b;其…

任务执行中拖延的认知神经机制

任务执行中拖延的认知神经机制 引言 虽然动机的产生往往是人们行动的前提(Ajzen, 2011;林琳&白新文,2014)&#xff0c;但动机的产生却并不必然地导致随后的行为(Rhodes&deBruijn,2013;Sniehotta, Scho1z, & Schwarzer, 2005)。动机向行为的转换依赖于一系列自我控…

北京市行政村边界shp数据/北京市乡镇边界/北京市土地利用分类数据

北京是一座有着三千多年历史的古都&#xff0c;在不同的朝代有着不同的称谓&#xff0c;大致算起来有二十多个别称。北京地势西北高、东南低。西部、北部和东北部三面环山&#xff0c;东南部是一片缓缓向渤海倾斜的平原。境内流经的主要河流有&#xff1a;永定河、潮白河、北运…

Ollama 只安装 Ollama,本地快速部署谷歌开源大模型Gemma(基于Ollama)

参考&#xff1a;本地快速部署谷歌开源大模型Gemma(基于Ollama) - 知乎 确保系统更新: Bash sudo apt update && sudo apt upgrade 需要先下载Ollama&#xff0c;版本要求0.1.26及以上 运行curl -fsSL https://ollama.com/install.sh | sh 监听 Ollama API 接…

常见的限流算法- python版本

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 个人IP&#xff1a;shigen 在系统的稳定性设计中&#xff0c;需要考虑到的就是限流&#xff0c;避免高并发…

【VUe】简略学习 vue

Vue 是一套用于构建用户界面的渐进式框架。要想使用这个框架&#xff0c;就需要先在页面中引用&#xff1a; 如何使用&#xff1a; 来到控制台&#xff1a; 数据绑定 若要在标签里替换&#xff0c;就需要使用 v-bind 指令了&#xff1a; 在标签里&#xff08;尖括号里&#xf…

数据库insert详细用法

数据库版本&#xff1a;KingbaseES V008R006C008B0014 简介 INSERT 语句用于将数据插入表中&#xff0c;向指定表格添加1行或多行数据&#xff0c;本篇文章主要以kingbase介绍insert的一些技巧。 文章目录如下 1. 基本语法 2. 实用技巧 2.1. 插入其他表数据 2.2. 快速插入万…

【力扣hot100】刷题笔记Day25

前言 这几天搞工作处理数据真是类似我也&#xff0c;还被老板打电话push压力有点大的&#xff0c;还好搞的差不多了&#xff0c;明天再汇报&#xff0c;赶紧偷闲再刷几道题&#xff08;可恶&#xff0c;被打破连更记录了&#xff09;这几天刷的是动态规划&#xff0c;由于很成…

HTML5七天学会基础动画网页10(2)

制作立方体 学完前面的基础内容&#xff0c;制作立方体是个不错的练习方法&#xff0c;先看成品 再分析一下&#xff0c;六个面让每个面旋转平移就可以实现一个立方体&#xff0c;来看代码: <title> 制作立方体</title> <style> *{ margin: 0; padding: 0; …

鸿蒙开发:从入门到精通的全方位学习指南

随着华为鸿蒙HarmonyOS生态系统的迅速扩展&#xff0c;越来越多的开发者渴望深入了解并掌握这一前沿技术。本文旨在为鸿蒙开发新手提供一份详尽且实用的学习教程&#xff0c;助您从零开始&#xff0c;逐步迈向鸿蒙开发的巅峰。 一、鸿蒙开发环境搭建 DevEco Studio安装&#x…

C语言--- 指针运算笔试题详解

目录 题目1&#xff1a; 题目2&#xff1a; 题目3&#xff1a; 题目4&#xff1a; 题目5&#xff1a; 题目6&#xff1a; 题目7&#xff1a; 题目1&#xff1a; #include <stdio.h> int main() {int a[5] { 1, 2, 3, 4, 5 };int *ptr (int *)(&a 1);print…

Open3D 利用四个点计算球心和半径 (28)

Open3D 利用四个点计算球心和半径 (28) 一、算法介绍二、算法实现1.代码2.结果一、算法介绍 给定的四个点坐标,计算球心和半径,提供验证的四个点来比较最终的结果是否准确。 二、算法实现 1.代码 代码如下(示例): import numpy as npdef calculate_sphere_center_…

课时61:流程控制_if条件控制_嵌套if实践

2.2.3 嵌套if实践 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 简介 一个if语句仅仅能够针对一个场景的多种情况。当我们面对多场景的条件判断的时候&#xff0c;一个if结构语句无法满足需求&#xff0c;这个时候&#xff0c;我…

海格里斯HEGERLS智能托盘四向车系统为物流仓储自动化升级提供新答案

随着实体企业面临需求多样化、订单履行实时化、商业模式加速迭代等挑战&#xff0c;客户对物流仓储解决方案的需求也逐渐趋向于柔性化、智能化。作为近十年来发展起来的新型智能仓储设备&#xff0c;四向车系统正是弥补了先前托盘搬运领域柔性解决方案的空白。随着小车本体设计…

【AI】如何创建自己的自定义ChatGPT

如何创建自己的自定义ChatGPT 目录 如何创建自己的自定义ChatGPT大型语言模型(LLM)GPT模型ChatGPTOpenAI APILlamaIndexLangChain参考推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课本文将记录如何使用OpenAI GPT-3.5模型、LlamaIndex和LangChain创建自己的…

Grunt、Gulp 与 webpack:谁更胜一筹?

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

PWM驱动智能小车舵机运动

文章目录 一、硬件电路二、舵机初始化三、舵机控制 一、硬件电路 通过TIMER3的通道3提供PWM驱动电机 二、舵机初始化 初始化让舵机位于最左边&#xff0c;也就是0。 static int ServoInit(struct Servo *ptdev){if(NULL ptdev){LogDebug("ServoInit EINVAL \r\n&qu…