7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

QuillをVueなどのSSRを加味して組み込む 他tips

Last updated at Posted at 2019-11-05

Quill

Quill https://github.com/quilljs/quill

Quill is a modern WYSIWYG editor built for compatibility and extensibility.

Quillはテキストエディタライブラリです。
拡張性も高いですが、特殊な仕様の理解が必要です。
Quillを扱う(拡張する)tipsの紹介をします。

QuillのSSR時のエラー回避

Vue.jsなどのSSR可能なフレームワークでSSR時にQuillをimportするとDOM系のAPIを参照しエラーになってしまいます。

スクリーンショット 2019-11-05 12.41.04.png

対策(Vue.jsの場合)

.vue
<div red="editor" />

<script>
let Quill = {}
if (process.client) {
  Quill = require('quill')
}

export default {
  ...
  mounted () {
    if (process.client) {
      const quill = new Quill(this.$refs.editor.$el)
    }
  }
}
</script>

サーバサイドではimportできない・importはブロックの中では実行できないのでrequireを使います。

改行時のスクロールをwindowする

Quillでは改行・折返しによりテキストの高さが変化した際の自動スクロールを親階層のDOMエレメントしか指定することができません
DOM構造や既存のスタイルの関係上windowをスクロールしたい場合が考えられます。

対策

.js
quill.selection.scrollIntoView = function (scrollingContainer) {
  const range = this.lastRange
  if (range == null) return
  const bounds = this.getBounds(range.index, range.length)
  if (bounds == null) return
  const limit = this.scroll.length() - 1
  const [first] = this.scroll.line(Math.min(range.index, limit))
  let last = first
  if (range.length > 0) {
    [last] = this.scroll.line(Math.min(range.index + range.length, limit))
  }
  if (first == null || last == null) return
  const scrollBounds = {
    top: 0,
    bottom: window.innerHeight
  }
  if (bounds.top < scrollBounds.top) {
    window.scrollBy(0, -(scrollBounds.top - bounds.top))
  } else if (bounds.bottom > scrollBounds.bottom) {
    window.scrollBy(0, bounds.bottom - scrollBounds.bottom)
  }
}

quillのscrollIntoViewの実装を参考にスクロール処理をwindowに差し替えましょう

ドラッグ&ドロップで画像を挿入する

quillにはドラッグ&ドロップの処理は組み込まれていないので自前で追加しましょう

.js
quill.container.addEventListener('drop', (event) => {
  if (!event.dataTransfer.files || event.dataTransfer.files.length == 0) {
    return
  }
  event.stopPropagation()
  event.preventDefault()

  const files = event.dataTransfer.files
  const file = files[0]
  const name = file.name
  const range = quill.getSelection(true)

  someUploadFunc(file).then(response => {
    quill.insertEmbed(range.index, 'image', response.url, 'user')
  }).catch(error => {
    console.error(error)
  })
}, false)
7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?