微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 React Quill 中实现受限编辑

如何解决在 React Quill 中实现受限编辑

我想用 react-quill 实现一个受限的编辑器。

要求:

  1. 有些文本用户不应更改。
  2. 用户可以更改一些文本。

我写了一些代码,但问题是我从 api 接收到一个带有通配符的 HTML 字符串。通配符表示这是一个受限文本

例如

<p>The subject property is located [Property Address].</p>

[物业地址] 应该是用户不可编辑的。

React-quill 代码

import React,{ useEffect,useRef } from "react";
import Reactquill,{ quill } from "react-quill";

const Delta = quill.import("delta");
const Embed = quill.import("blots/block/embed");

class PlaceholderBlot extends Embed {
  static create(value) {
    let node = super.create(value);
    node.setAttribute("data-label",value.label);
    node.innerText = value.label;

    return node;
  }

  static value(domNode) {
    return domNode.dataset;
  }

  length() {
    return 1;
  }

  deleteAt() {
    return false;
  }
}

class Placeholder {
  constructor(quill,options) {
    this.quill = quill;
    this.onTextChange = this.onTextChange.bind(this);
    this.onSelectionChange = this.onSelectionChange.bind(this);

    this.quill.on(quill.events.TEXT_CHANGE,this.onTextChange);
    this.quill.on(quill.events.SELECTION_CHANGE,this.onSelectionChange);
  }

  onTextChange(_,oldDelta,source) {
    if (source !== quill.sources.API) {
      const currrentContents = this.quill.getContents();
      const delta = currrentContents.diff(oldDelta);

      const revertOps = delta.ops.filter(
        (op) => op.insert && op.insert.placeholder
      );
      if (!revertOps.length) return;

      const [retainop] = delta.ops.filter((op) => op.retain);

      if (retainop) {
        this.quill.updateContents(new Delta([retainop,...revertOps]));
        this.quill.setSelection(retainop.retain + 1 + revertOps.length);
      } else {
        this.quill.updateContents(new Delta(revertOps));
        this.quill.setSelection(revertOps.length);
      }
    }
  }

  onSelectionChange(range,oldRange,source) {}
}

const addRestrictedText = (quill,html) => {
  const position = quill.getLength() || 0;

  quill.insertEmbed(
    position,"placeholder",{ label: html },quill.sources.API
  );
};

const addSimpleHtml = (quill,html) => {
  const delta = quill.clipboard.convert(html);
  const existingDelta = quill.getContents();
  console.log(existingDelta);
  if (existingDelta.ops[0].insert === "\n") {
    quill.setContents(delta);
  } else {
    const combinedDelta = existingDelta.concat(delta);
    quill.setContents(combinedDelta);
  }
};

export default function quillEditor() {
  const editor = useRef(null);
  PlaceholderBlot.blotName = "placeholder";
  PlaceholderBlot.tagName = "strong";
  PlaceholderBlot.className = "ql-placeholder-content";

  quill.register(PlaceholderBlot);
  quill.register("modules/placeholder",Placeholder);

  useEffect(() => {
    const quill = editor.current.getEditor();

    addSimpleHtml(quill,"<p>The subject property is located");
    addRestrictedText(quill,"[Property Address]");
    addSimpleHtml(quill,".</p>");
  },[editor]);

  return (
    <Reactquill
      ref={editor}
      modules={{
        toolbar: [
          [{ header: [1,2,false] }],["bold","italic","underline"],["image","code-block"],],placeholder: {},history: {
          userOnly: true,},}}
    />
  );
}

用法

<quillEditor />

代码的问题是受限文本将包含在段落中,但我可以分别输入普通文本和受限文本,当我分别输入它们时,它们会转换为不同的段落,从而产生换行符。

这里我复制了stackblitz

中的例子

编辑:我可以对 onchange 事件做些什么来以编程方式实现此功能

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。