如何在非Vue项目中使用vue-quill-editor实现粘贴纯文本功能?

在一个非Vue项目构建的、仅是普通的JavaScript项目里,只是简单地在页面引入了quill.js、vue-quill-editor.js、vue.js。

  1. 需要实现在vuequilleditor中粘贴文本时,将粘贴的富文本转换文纯文本,并插入到光标所在位置。
  2. 如果光标选中了部分内容,需要将选中的内容替换为粘贴文本。
  3. 插入文本后,需要修改光标位置到插入文本的后面
  4. 即使当前光标所在的位置(选中的文本)带有css样式,粘贴后的文本也不能带有样式。
<html>

<head>
  <link rel="stylesheet" href="https://unpkg.com/quill@1.3.7/dist/quill.core.css">
  <link rel="stylesheet" href="https://unpkg.com/quill@1.3.7/dist/quill.snow.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
  <script src="https://unpkg.com/quill@1.3.7/dist/quill.js"></script>
  <script src="https://unpkg.com/vue-quill-editor@3.0.6/dist/vue-quill-editor.js"></script>
</head>

<body>
  <div id="main">
    <div style=" height: 100px;">
      <quill-editor :options="editorOption" ref="myQuillEditor"></quill-editor>
    </div>
  </div>
  <script type="application/javascript">
    Vue.use(window.VueQuillEditor)
    var toolbarOptions = [
      ['bold', 'underline'],
      [{ 'color': ['blue', 'red', 'black'] }],
      ['link'],
      ['clean']
    ]
    var main = new Vue({
      el: "#main",
      data: {
        QuillEditors: [],
        editorOption: {
          scrollingContainer: null,
          modules: {
            toolbar: toolbarOptions
          },
          theme: 'snow'
        },
      },
      methods: {
      }
    })
  </script>
</body>

</html>

我尝过使用mounted函数,监听‘paste’事件,然后获取剪切板内容的文本格式(text/plain),再调用quill的insertText方法将文本内容插入。
但是插入后,文本内容会受到 插入index所在的delta的样式的影响?

同样,删除时使用deleteText、insertText方法,结果也都不理想。


感谢maxkiicc大佬的帮助.

<html>

<head>
  <link rel="stylesheet" href="https://unpkg.com/quill@1.3.7/dist/quill.core.css">
  <link rel="stylesheet" href="https://unpkg.com/quill@1.3.7/dist/quill.snow.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
  <script src="https://unpkg.com/quill@1.3.7/dist/quill.js"></script>
  <script src="https://unpkg.com/vue-quill-editor@3.0.6/dist/vue-quill-editor.js"></script>
</head>

<body>
  <div id="main">
    <div style=" height: 100px;">
      <quill-editor :options="editorOption" ref="myQuillEditor"></quill-editor>
    </div>
  </div>
  <script type="application/javascript">
    Vue.use(window.VueQuillEditor)
    var toolbarOptions = [
      ['bold', 'underline'],
      [{ 'color': ['blue', 'red', 'black'] }],
      ['link'],
      ['clean']
    ]
    var main = new Vue({
      el: "#main",
      data: {
        QuillEditors: [],
        editorOption: {
          scrollingContainer: null,
          modules: {
            toolbar: toolbarOptions
          },
          theme: 'snow'
        },
      },
      mounted () {
        const NODE_TYPE = {
          ELEMENT_NODE: 1
        }
        var quill = this.$refs.myQuillEditor.quill
        quill.clipboard.matchers = quill.clipboard.matchers.filter(item => (item[0] !== "i" && item[0] !== "b"))
        quill.clipboard.addMatcher(NODE_TYPE.ELEMENT_NODE, function (node, delta) {
          var newLine = false
          if (delta.ops.length > 0 && delta.ops[0].insert.includes("\n")) {
            newLine = true
          }
          var plaintext = node.innerText
          if (newLine) {
            plaintext = plaintext + "\n"
          }
          var Delta = Quill.import("delta")
          var newDelta = new Delta().insert(plaintext)
          return newDelta
        })
      }
    })
  </script>
</body>

</html>
阅读 656
1 个回答

先说下解决方法吧,之前的思路太过复杂,Quill提供了clipboard.addMatcher方法,可以自定义粘贴的内容,通过clipboard.addMatcher方法,我们可以将粘贴的富文本转换为纯文本。

initQuill() {
  const NODE_TYPE = {
    ELEMENT_NODE: 1
  }
  const quill = this.$refs.myQuillEditor.quill;
  quill.clipboard.addMatcher(NODE_TYPE.ELEMENT_NODE, function (node, delta) {
    // 获取粘贴的纯文本
    var plaintext = node.innerText;
    var Delta = Quill.import("delta");
    return new Delta().insert(plaintext);
  });
},

https://quilljs.com/docs/modules/clipboard

https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType

然后你说的那个问题确实了触发了Quill的onPaste事件,它的回调函数中有一个异步事件,导致delta的更新发生了冲突。而且自定义paste事件会让它原本的一些功能失效。

image.png

----------update----------------------

不确定使用insertText会不会受到外部样式的影响,但是QuillJs提供了使用Delta来编辑内容的api,你可以使用updateContents来更新当前富文本编辑器的内容。Delta本身是不包含当前操作 Index 的,所有操作都是从头开始,可以用retain保留光标index之前的内容。

https://quilljs.com/docs/api#updatecontents

https://quilljs.com/docs/delta#playground

但是我在测试过程中,当index === 0的时候会报错,感觉是QuillJS的问题,你可以对delta的细节处理一下。

image.png

pasteListenerCb(event) {
  event.preventDefault();
  let paste = (event.clipboardData || window.clipboardData).getData("text");
  this.clipboardData = paste;

  const pasteLength = paste.length;
  const quill = this.$refs.myQuillEditor.quill;
  const index = quill.selection.savedRange.index;

  quill.updateContents([
    {
      retain: index,
    },
    {
      insert: paste,
    },
  ]);
},
推荐问题
宣传栏