跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 开源一个 React 技术栈的高扩展性富文本编辑器
未分類
23 6 月 2020

开源一个 React 技术栈的高扩展性富文本编辑器

开源一个 React 技术栈的高扩展性富文本编辑器

資深大佬 : camol 3

最近我花了点时间,把之前使用旧版的 slate 框架积累的一些经验整理了下,开源一个基于 slate 框架的 react 技术栈的高扩展性的富文本编辑器。

它的高扩展性主要在于:

  1. 支持自定义工具栏;
  2. 支持自定义节点渲染 ;

简要 demo 如下

import * as React from "react"; import ReactDom from "react-dom"; import EasyEditor from "@camol/easy-editor";  class Editor extends React.Component {   html = "";    handleChange = (v: any) => {     console.log("change=>>>", v);     if (this.editorRef.current) {       // value to html       console.log(this.editorRef.current.convertor.serialize(v.change.value));     }   };    render() {     return <EasyEditor value={"<p>123</p>"} onChange={this.handleChange} />;   } }  ReactDom.render(<Editor />, document.getElementById("root"));  

value 支持 slate 的 Value 实例,也支持 html 。所以,你可以调用 value.toJSON() 取得 json 格式的数据 或者转成 html 存入数据库,回显时可以直接使用。

支持自定义工具栏

目前,编辑器已经内置了一些工具,如文字加粗、斜体、下划线、文字居中等功能。支持图片和视频的插入,资源地址可以通过 beforeUpload 自定义上传逻辑。从剪贴板内复制粘贴图片(包括 word 内复制)等上传文件部分都会尝试调用该函数以获取上传后的资源地址。不使用自定义上传时,图片地址默认使用 base64 格式。

悬浮工具栏,考虑到选中不同节点时的渲染不同,还没考虑好如何设计,暂时注释掉了这部分功能,后面会完善。

开源一个 React 技术栈的高扩展性富文本编辑器

// 自定义 插入视频的操作按钮 class AudioControl extends React.Component {   inputRef = React.createRef();    handleClick = () => {     if (inputRef.current) {       inputRef.current.click();     }   };    handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {     const file = e.target.files[0];     e.target.value = "";     if (file) {       if (this.props.beforeUpload) {         let url = await this.props.beforeUpload(file);         if (url) {           let change = this.props.change.focus().insertInline({             object: "inline",             type: "audio",             isVoid: true,             data: {               src: url,             },           });           this.props.update(change);         }       }     }   };    render() {     return (       <span onMouseDown={this.handleClick}>         <span className="tool-insert-video" />         <input           type="file"           style={{ width: 0, height: 0, opacity: 0 }}           ref={this.inputRef}           onChange={this.handleChange}         />       </span>     );   } } 
<EasyEditor     value={"<p>123</p>"}     onChange={this.handleChange}     controls={[       ["bold", "u", "image"],       [         {           type: "audio",           component: (change, update, beforeUpload) => {             return (               <AudioControl                 change={change}                 update={update}                 beforeUpload={beforeUpload}               />             );           },         },       ],     ]}   />  

支持自定义节点渲染

使用自定义节点渲染,可以实现一些高级功能,如图片拖拽调整大小,图片悬浮、左环绕、右环绕等功能,或者表格的拖拽调整等,又或者是类似石墨文档等添加文件附件,展示在文档中的功能。前面部分功能已经在编辑器内实现了。

这里我简要展示下如何自定义渲染 audio 标签:

import * as React from "react"; import { DefaultTreeElement } from "parse5";  const plugin = {   type: "node", // node, mark   object: "inline", // block, inline   nodeType: "super-audio", // 自定义节点类型   // 自动解析 html 中 audio 标签,生成 super-audio 节点   importer(el: DefaultTreeElement, next: Function): any {      if (el.tagName.toLowerCase() === "audio") {       return {         object: "inline", // block 、inline,         type: "super-audio",         isVoid: true,         data: {           src: el?.attrs?.find((n) => n.name === "src")?.value,         },         nodes: next(el.childNodes),       };     }   },   // 调用 editor.convertor.serialize(value) 会调用该方法将 super-audio 节点 转成 对应的 html 存入数据库   exporter(node: any, children: any): any {      let { className, src } = node.data.toJS();     return <audio src={src} className={className}></audio>;   },   // 自定义渲染方式   render(     editor: any,     props: { attributes: any; children: any; node: any; isSelected: any }   ): any {     // @ts-ignore     const { attributes, children, node, isSelected } = props;     const src = node.data.get("src");     return (       <span {...attributes}>         <audio src={src} controls>           {children}         </audio>       </span>     );   }, };  export default plugin; 
<EasyEditor     value="<audio src='xxxxx.mp3'></audio><p> </p>"     ...     plugins={[audioPlugin]} /> 

目前编辑器中的视频播放插件就是使用该特性实现的,集成了 plyr-react,支持 mp4 、webm (其他格式后面会支持)。 开源一个 React 技术栈的高扩展性富文本编辑器

求支持

虽然可能还有些问题,但我后面会长期维护的,希望对需要的同学们有帮助 :)。

最后贴一下该项目的 github 地址,求支持,求 star !

https://github.com/kanweiwei/easy-editor

大佬有話說 (0)

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具