富文本編輯器Quill(二)上傳圖片與視頻

image與video在Quill formats中屬於Embeds,要在富文本中插入圖片或者視頻須要使用insertEmbed api。javascript

insertEmbed

insertEmbed(index: Number, type: String, value: any, source: String = 'api'): Delta

插入圖片須要位置,內容類型以及圖片的url:java

quill.insertEmbed(10, 'image', 'https://quilljs.com/images/cloud.png')

獲取位置:node

const range = quill.getSelection();

上傳圖片

首先toolbar中添加image,還須要一個隱藏input元素用來上傳圖片:web

<template>
  <div>
    <div id="toolbar">
      <span class="ql-formats">
        <button class="ql-image"></button>
        <button class="ql-video"></button>
      </span>
    </div>
    <div id="editor">
      <p>Hello World!</p>
      <p>Some initial <strong>bold</strong> text</p>
      <p><br></p>
    </div>
    <input id="uploadImg" type="file" style="display:none" accept="image/png, image/jpeg, image/gif" @change="uploadImage">
  </div>
</template>

爲image添加handler,點擊時上傳圖片:ajax

this.quill.getModule("toolbar").addHandler("image", this.uploadImageHandler)

handler:小程序

    uploadImageHandler () {
      const input = document.querySelector('#uploadImg')
      input.value = ''
      input.click()
    },

爲input元素添加onchange事件,獲取上傳圖片,上傳服務器,獲取圖片地址,將地址插入到編輯器中:api

  async uploadImage (event) {
      const form = new FormData()
      form.append('upload_file', event.target.files[0])
      const url = await $.ajax(...)  #上傳圖片 獲取地址
      const addImageRange = this.quill.getSelection()
      const newRange = 0 + (addImageRange !== null ? addImageRange.index : 0)
      this.quill.insertEmbed(newRange, 'image', url)
      this.quill.setSelection(1 + newRange)
    }

  所有代碼:服務器

<template>
  <div>
    <div id="toolbar">
      <span class="ql-formats">
        <button class="ql-image"></button>
        <button class="ql-video"></button>
      </span>
    </div>
    <div id="editor">
      <p>Hello World!</p>
      <p>Some initial <strong>bold</strong> text</p>
      <p><br></p>
    </div>
    <input id="uploadImg" type="file" style="display:none" accept="image/png, image/jpeg, image/gif" @change="uploadImage">
  </div>
</template>

<script>
import Quill from 'quill'

export default {
  name: "QuillEditor",
  mounted () {
    this.initQuill()
  },
  beforeDestroy () {
    this.quill = null
    delete this.quill
  },
  methods: {
    initQuill () {
      const quill = new Quill('#editor', {
        theme: 'snow',
        modules: {
          toolbar: '#toolbar'
        }
      })
      this.quill = quill
      this.quill.getModule("toolbar").addHandler("image", this.uploadImageHandler)
    },
    uploadImageHandler () {
      const input = document.querySelector('#uploadImg')
      input.value = ''
      input.click()
    },
    async uploadImage (event) {
      const form = new FormData()
      form.append('upload_file', event.target.files[0])
      const url = await $.ajax(...)
      const addImageRange = this.quill.getSelection()
      const newRange = 0 + (addImageRange !== null ? addImageRange.index : 0)
      this.quill.insertEmbed(newRange, 'image', url)
      this.quill.setSelection(1 + newRange)
    }
  }
}
</script>

上傳視頻作些少量修改就能夠了:app

<input id="uploadVideo" type="file" style="display:none" accept="video/*" @change="uploadVideo">
this.quill.getModule("toolbar").addHandler("video", this.uploadVideoHandler)
uploadVideoHandler () {...}
async uploadVideo (event) {...}

定製Video

默認的video上傳會存在一個問題,上傳後video是放在iframe中的,通常狀況下是沒有問題的,但在小程序中使用h5頁面時,iframe中的域名須要添加到小程序業務域名中,不然會禁止訪問。async

更好的解決方法是簡單的添加一個video元素,而不是iframe,咱們須要定製一個Video Embed。

const BlockEmbed = Quill.import('blots/block/embed')
class VideoBlot extends BlockEmbed {
  static create (value) {
    let node = super.create()
    node.setAttribute('src', value.url)
    node.setAttribute('controls', value.controls)
    node.setAttribute('width', value.width)
    node.setAttribute('height', value.height)
    node.setAttribute('webkit-playsinline', true)
    node.setAttribute('playsinline', true)
    node.setAttribute('x5-playsinline', true)
    return node;
  }

  static value (node) {
    return {
      url: node.getAttribute('src'),
      controls: node.getAttribute('controls'),
      width: node.getAttribute('width'),
      height: node.getAttribute('height')
    };
  }
}

註冊:

VideoBlot.blotName = 'simpleVideo'
VideoBlot.tagName = 'video'
Quill.register(VideoBlot)

插入Embed:

      this.quill.insertEmbed(newRange, 'simpleVideo', {
        url,
        controls: 'controls',
        width: '100%',
        height: '100%'
      })

添加效果:

<video src="...mp4" controls="controls" width="100%" height="100%" webkit-playsinline="true" playsinline="true" x5-playsinline="true"></video>
相關文章
相關標籤/搜索