web-富文本quill - 1

server/2024/11/14 11:52:08/

简介: quill 是一个跨平台的功能强大的富文本编辑器。开发者可以通过简单的API来控制编辑器的内容。

 

Parchment:Parchment是Quill的文档模型。它是DOM树的并行树结构,并提供了对内容编辑器(如Quill)有用的功能。Parchment树由Blob组成
Blot:Blot是Parchment文档的组成部分,它是quilljs中最重要的抽象。有了Blot,可以让用户对编辑器中的内容进行操作,而无需对DOM进行直接操作
Delta: 是一个扁平的JSON数组,用于保存(描述)编辑器中的内容数据。Delta中的每一项代表了一次操作,它的变化会直接影响到编辑器中内容的变化


 核心组件:
    Parchment:是指定义和管理文本格式的模块。
    Blot:则代表了Quill中的基本构建单元,可以理解为一个可编辑区域内的一段内容。
    Delta:是Quill使用的一种数据格式,用于表示富文本编辑器中的内容和样式。
三者关系
    在Quill富文本编辑器中,Parchment用于定义和管理文本格式(如字体、颜色等),
    而Blot则代表了编辑器中的基本构建单元,
    在Delta数据格式中被使用来表示这些内容和样式


Delta 的数据格式:
    {
      ops: [
        { insert: 'Gandalf', attributes: { bold: true } },
        { insert: ' the ' },
        { insert: 'Grey', attributes: { color: '#cccccc' } },
        {
          insert: {image: 'https://quilljs.com/assets/images/icon.png'},
          attributes: {
            link: 'https://quilljs.com'
           }
          },
          { insert: 'The Two Towers' },
        { insert: '\n', attributes: { header: 1 } },
        { insert: 'Aragorn sped on up the hill.\n' }
      ]
    }
  操作函数:insert,delete,retain
  文档函数:concat,diff,eachline,invert
  Utility: filter,forEach,length,partition,reduce,slice
  转换函数: compose,transform,transformPosition


 Blots: 
      
      domNode: Node;
      static tagName: 'div'      ; html 标签
      static className:''            ; 生成html 代码中的class  
      static blotName: 'block' ;  
      static allowedChildren :[] ; 允许的的子级标签,
      static defaultChild: Registry.BlotConstructor;
      children: LinkedList<Blot>; 
      update(mutations: MutationRecord[], context: { [key: string]: any });
          //Blot发生变化时会被调用,参数mutation的target是blot.domNode。在同一次更新循环中,所有blots收到的sharedContext是相同的。
      optimize(context: { [key: string]: any }): void;
          //更新循环完成后会被调用,避免在optimize方法中改变document的length和value

      value(): any; // 返回的值
      static formats(domNode: Node);
      format(format: name, value: any);
      formats(): Object;
      wrap(name: string, value?: any): Parent;
    wrap(wrapper: Parent): Parent;
    deleteAt(index: number, length: number): void;
    formatAt(index: number, length: number, name: string, value: any): void;
    insertAt(index: number, value: string, def?: any): void;


ShadowBlot 中
  static requiredContainer:  定义该Blot需要被哪一个容器Blot包裹。当该Blot被创建完成后,会执行到ShadowBlot类中的optimize方法,其主要逻辑就是:检查该Blot的requiredContainer是否被设置,并且该Blot的父Blot不是requiredContainer设置的Blot类的实例,调用wrap方法(wrap的作用就是创建容器Blot实例,插入的该Blot的父级中,然后将该Blot插入到容器中)。

 quill中的内置Blot都继承自ShadowBlot。 每个blot都拥有以下这些引用属性
     .parent—父级blot,包含当前blot。若当前blot是顶级blot,则为null。
    .prev—上一个同级blot, 与当前blot拥有同一个parent, 若当前blot为第一个child,则为null。
    .next—下一个同级blot, 与当前blot拥有同一个parent, 若当前blot为最后一个child,则为null。
    .scroll—顶级blot,后面会提供更多关于scroll blot的信息。
    .domNode—当前blot的DOM结构,该blot在DOM树中的实际结构。
 


  生命周期:
      static create(initialValue): 
          用于根据初始值创建DOM Node。这里也非常适合在node上设置一些与Blot实例无关的初始属性。该函数会返回新创建的DOM Node,但并未插入文档中
          create()并不是任何时候都会在blot实例化前执行,例如:当用户通过 复制/粘贴 创建blot时,blot的创建会直接接受来自剪切板的HTML结构,从而跳过create方法。
      constructor(domNode): 构造函数,通过domNode实例化blot。在这里可以做一些通常在class的构造函数中做的事情,比如:事件绑定,缓存引用等。
      static register(): 注册


开发一个嵌套组件基本思路流程(table 为例):
    1: 先定义 table,theader,tobody,tr,td,th 这几个Blot,
        在optimize 中判断是否帮定了上级,如果绑定则调用warp()
             if (
          this.statics.requiredContainer &&
          !(this.parent instanceof this.statics.requiredContainer)
        ) {
             this.wrap(this.statics.requiredContainer.blotName,{
                  row: rowId,
                  colspan,
                  rowspan
             })
        }

    2: 配置嵌套关系:
        tableBlot.allowedChildren = [tbodyBlot,theaderBlot]
        tbodyBlot.requiredContainer = tableBlot
        theaderBlot.requiredContainer = tableBlot

        tbodyBlot.allowedChildren = [trBlot]
        trBlot.requiredContainer = tbodyBlot

        trBlot.allowedChildren = [thBlot,tdBlot]
        thBlot.requiredContainer =  trBlot
        tdBlot.requiredContainer =  trBlot

相关文献地址:
    https://github.com/quilljs/parchment/
    https://github.com/quilljs/delta
    https://juejin.cn/post/6844903838982340622
    https://juejin.cn/post/6844903844749508621


http://www.ppmy.cn/server/42491.html

相关文章

C++ 模板

模板的原理 模板是编译器在编译时进行代码生成的过程。编译器会根据模板的参数类型,生成对应的具体代码。 模板参数化可以是类型参数,也可以是非类型参数(如整数常量)。编译器会为每种不同的参数类型生成专门的代码实例。 模板通过函数重载和类型推导的机制来确定使用哪个模板…

【数据结构】——时间复杂度与空间复杂度

时间复杂度与空间复杂度 数据结构算法算法效率时间复杂度大O的渐进表示法 空间复杂度常见复杂度对比 数据结构 数据结构是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种一种或者多种特定关系的数据元素的集合 数据结构就是内存中对数据进行管理 算法 算法就是定…

《Python编程从入门到实践》day37

# 昨日知识点回顾 制定规范、创建虚拟环境并激活&#xff0c;正在虚拟环境创建项目、数据库和应用程序 # 今日知识点学习 18.2.4 定义模型Entry # models.py from django.db import models# Create your models here. class Topic(models.Model):"""用户学习的…

GPT搜索引擎原型曝光!

OpenAI发布会前一天&#xff0c;员工集体发疯中……上演大型套娃行为艺术。 A&#xff1a;我为B的兴奋感到兴奋&#xff1b;B&#xff1a;我为C的兴奋感到兴奋……Z&#xff1a;我为这些升级感到兴奋 与此同时还有小动作不断&#xff0c;比如现在GPT-4的文字描述已不再是“最先…

关于如何创建一个可配置的 SpringBoot Web 项目的全局异常处理

前情概要 这个问题其实困扰了我一周时间&#xff0c;一周都在 Google 上旅游&#xff0c;我要如何动态的设置 RestControllerAdvice 里面的 basePackages 以及 baseClasses 的值呢&#xff1f;经过一周的时间寻求无果之后打算决定放弃的我终于找到了一些关键的线索。 当然在此…

BGP联邦实验

实验要求及拓扑如下 1.子网划分 AS2基于172.16.0.0/16进行网段划分 划分出掩码为30的网段分给R2-R7作为PC&#xff0c;划分出掩码为24的网段作为AS2内部路由器之间的链路网段 172.16.0.0/30 172.16.0.4/30 172.16.0.8/30 172.16.0.12/30 172.16.0.16/30 …

楼道堆积物视觉识别监控系统

楼道堆积物视觉识别监控系统采用了AI神经网络和深度学习算法&#xff0c;楼道堆积物视觉识别监控系统通过摄像头实时监测楼道的情况&#xff0c;通过图像处理、物体识别和目标跟踪算法&#xff0c;系统能够精确地识别楼道通道是否被堆积物阻塞。楼道堆积物视觉识别监控系统检测…

生信机器学习入门1 - 数据预处理与线性回归(Linear regression)预测

数据预处理与线性回归&#xff08;Linear regression&#xff09;预测 数据集下载 # data文件夹中包含数据集文件 git https://github.com/LittleGlowRobot/machine_learning.git数据预处理主要步骤 参考github。 读取数据集 import numpy as np import pandas as pd####…