Open metroluffy opened 6 years ago
Quill.js是一款可以灵活自定义的开源的富文本编辑器,Github上已经有1.8W+的star了。拖拽上传有着良好的交互体验,原生的Quill并不支持图片拖拽上传功能,本文以插件的形式来实现。 Quill.js有着强大且灵活的插件系统,很简单便可以实现一个插件,下面是一个基本的插件模型。
class Plugin { /** * @param quill {Quill}富文本实例 * @param options {Object} */ constructor(quill, options = {}) { this.quill = quill this.options = options } } export { Plugin }
上述这个模型并不包含任何功能,接下来我们来实现一个简单的统计文章字数的插件。
class wordCount { constructor(quill, options = {}) { this.quill = quill; this.options = options; this.quill.on('text-change', this.update.bind(this)); this.toolbar = quill.getModule('toolbar'); this.update(); // Account for initial contents } calculate(){ return this.quill.getLength() - 1 // quill.getLength() gives 1 instead of 0 when there is no content, so there need -1 } update() { const self = this let length = this.calculate(); let label = 'word'; if (length !== 1) { label += 's'; } let countView = document.querySelector('#quill-word-count'); if (!countView) { countView = document.createElement('span'); countView.id = 'quill-word-count'; self.toolbar.container.appendChild(countView); } countView.innerHTML = length + ' ' + label; } } export { wordCount }
text-change当Quill的内容发生变化时发出,是Quill提供的事件系统中的一个,然后使用getLength获取字数并更新在ToolBar的状态。接下来我们继续前进,HTML5提供了Darg & Drop API,以之来实现图片拖拽上传。
text-change
import defaultsDeep from 'lodash/defaultsDeep' const DefaultOptions = { url: '', size: 0, onUpload: false, onUploadSuccess: false, onUploadFaild: false, onSizeError: false, onTypeError: false } class ImageUploadExtend { /** * @param quill {Quill}富文本实例 * @param options {Object} config */ constructor(quill, options = {}) { this.quill = quill this.options = this. = defaultsDeep({}, options, DefaultOptions); this.file = '' // 要上传的图片文件 this.imgURL = '' // 图片地址 quill.root.addEventListener('drop', this.dropHandle.bind(this), false) quill.root.addEventListener('dropover', function (e) { e.preventDefault() }, false) } dropHandle (e) { const self = this e.preventDefault() self.file = e.dataTransfer.files[0]; // only one single image if (!self.file.type.match(/^image\/(gif|jpe?g|a?png|svg|webp|bmp|vnd\.microsoft\.icon)/i)) { // file is not an image // Note that some file formats such as psd start with image/* but are not readable if (self.options.onTypeError) { self.options.onTypeError() } return } // if set a size if (self.options.size !== 0 && self.file.size >= self.options.size * 1024 * 1024) { if (self.options.sizeError) { self.options.sizeError() } return } // if has`t url, insert img as Base64 source if (this.options.url !== '') { self.uploadImage() } else { self.toBase64() } } uploadImage () { } toBase64 () { const self = this const reader = new FileReader() console.log('--------把图片转换为Base64格式--------') reader.readAsDataURL(self.file) reader.onload = (e) => { // 返回base64 self.imgURL = e.target.result self.insertImage() } } insertImage () { const self = this const index = (self.quill.getSelection() || {}).index || self.quill.getLength() - 1 self.quill.insertEmbed(index, 'image', self.imgURL, 'user') self.quill.update() self.quill.setSelection(index + 1) } } export { ImageUploadExtend }
上述这个类基本实现了图片拖拽上传的功能,具体的上传逻辑比较简单就不写出了。接下来我们在Quill中注册该插件,就可以使用了。
import Quill from 'quill' import {ImageUploadExtend} from './ImageUploadExtend' Quill.register('modules/ImageUploadExtend', ImageUploadExtend) new Quill('#editor-container', { theme: 'snow', modules: { ImageUploadExtend: { url: '' }, } });
Quill Toolbar默认的图片按钮是将图片转成Base64格式插入内容,图片太大的话就不再合适,Toolbar Module允许添加自定义的处理函数进行配置,我们简单改造一下,在上述ImageUploadExtend这个类中加入相应的逻辑。
// add these code in ImageUploadExtend constructor constructor(quill, options = {}) { ... quill.getModule('toolbar').addHandler('image',this.toolBarImageHandler.bind(this)) } //implementation toolBarImageHandler () { const self = this let fileInput = document.querySelector('.quill-image-input'); if (!fileInput) { fileInput = document.createElement('input'); fileInput.setAttribute('type', 'file'); fileInput.setAttribute('accept', 'image/*'); fileInput.classList.add('quill-image-input'); fileInput.style.display = 'none' // 监听选择文件 fileInput.addEventListener('change', function () { self.file = fileInput.files[0] fileInput.value = '' // if set a size if (self.options.size !== 0 && self.file.size >= self.options.size * 1024 * 1024) { if (self.options.sizeError) { self.options.sizeError() } return } if (self.options.url !== '') { self.uploadImage() } else { self.toBase64() } }) document.body.appendChild(fileInput); } fileInput.click(); document.body.removeChild(fileInput); }
以上,基本实现了Quill.js图片上传的功能,文件上传也是一致的实现思路。有什么问题,可以进一步在评论中交流。下一篇打算写下如何给图片上传增加进度条的功能。
Quill.js Documentation
文字拖拽事件如何监听...
我拖拽后发现该拖拽内容的 id 不见了. 样式也不见了...
不太能get到你的场景哈,如果是文本节点之间拖拽更改顺序这类的话,看下实现是不是生成的新节点,能否手动加上去。节点拖拽也有很多优秀的开源库,也可以看看
Quill.js是一款可以灵活自定义的开源的富文本编辑器,Github上已经有1.8W+的star了。拖拽上传有着良好的交互体验,原生的Quill并不支持图片拖拽上传功能,本文以插件的形式来实现。 Quill.js有着强大且灵活的插件系统,很简单便可以实现一个插件,下面是一个基本的插件模型。
上述这个模型并不包含任何功能,接下来我们来实现一个简单的统计文章字数的插件。
text-change
当Quill的内容发生变化时发出,是Quill提供的事件系统中的一个,然后使用getLength获取字数并更新在ToolBar的状态。接下来我们继续前进,HTML5提供了Darg & Drop API,以之来实现图片拖拽上传。上述这个类基本实现了图片拖拽上传的功能,具体的上传逻辑比较简单就不写出了。接下来我们在Quill中注册该插件,就可以使用了。
Quill Toolbar默认的图片按钮是将图片转成Base64格式插入内容,图片太大的话就不再合适,Toolbar Module允许添加自定义的处理函数进行配置,我们简单改造一下,在上述ImageUploadExtend这个类中加入相应的逻辑。
以上,基本实现了Quill.js图片上传的功能,文件上传也是一致的实现思路。有什么问题,可以进一步在评论中交流。下一篇打算写下如何给图片上传增加进度条的功能。
参考资料
Quill.js Documentation