quill 富文本编辑器自定义视频上传(修改默认按钮行为)
前言
上一篇是修改官方的图片上传行为,这次是修改官方视频按钮默认行为,你会发现官方的视频默认行为,总是采用iframe
的形式,如果我们希望是原生video元素,就没办法了,于是就有了本篇教程。
这次自定义和图片就略有不同了,我们不能直接这么插入:
editor.insertEmbed(range.index, 'video', src, Quill.sources.USER);
如果采用这种方式,会导致和官方的行为一致,变成插入的是iframe
元素了。
为此,我们需要了解一个新知识:Blot
官方文档对于Blot的介绍很少,我们可以理解是一种行为扩展的方式,可以对用户输入的内容进行转换,比如格式化文本,加粗,包括本次的插入video元素,其实都是一种blot,官方通过register
方法,将行为扩展进行注册,从而实现功能扩展。
官方其实预设了一些Blot,我们可以基于这些进行扩展:
Text Blot(文本)
- 表示普通的文本内容,是最基本的Blot类型。
Block Blot(块)
- 表示一个块级元素,如段落、标题等。它可以包含多个Text Blot。
Inline Blot(内联)
- 表示内联元素,如加粗、斜体、链接等。它可以包含多个Text Blot。
Container Blot(容器)
- 表示一个容器元素,可以包含其他的Blot类型。常见的容器Blot有List(列表)和Table(表格)。
除了这些基本的Blot类型,Quill还提供了一些特殊的Blot类型,用于处理特定的功能和样式,例如:
Embed Blot(嵌入)
- 表示嵌入式内容,如图片、视频等。Embed Blot可以包含其他的Blot类型,用于表示嵌入内容的各个部分。
扩展视频,我们通过Block Blot就行了,blot有一些预设静态属性,因为它本身是一个class
,其中blotName
、tagName
都是必填的,className
可写可不写,写了他就是你配置的tagName
元素的类名。
教程
先创建一个用于视频的blot,新建videoEmbed.ts
文件,内容如下:
import Quill from 'quill';
const blockEmbed = Quill.import('blots/block/embed');
class VideoEmbed extends blockEmbed {
static blotName = 'VideoEmbed';
static tagName = 'video';
static create(url: string) {
const node = super.create();
node.setAttribute('src', url);
node.setAttribute('controls', '');
node.setAttribute('controlslist', 'nodownload noremoteplayback noplaybackrate');
node.setAttribute('disablepictureinpicture', '');
return node;
}
static value(node: any) {
return node.getAttribute('src');
}
}
export default VideoEmbed;
可以看到创建了一个node节点,然后设置了一些video的属性,具体的意义可以问ai,配置完毕后导出。
下面就是进行注册,必须是通过import引入的Quill
注册,官方要求全局,所以不能通过实例的方式注册。
import Quill from 'quill';
import 'quill/dist/quill.snow.css';
import VideoEmbed from './blot/videoEmbed';
Quill.register(VideoEmbed);
现在我们就可以开始自定义视频上传了。
<!-- 视频 -->
<input class="quill-editor-input-file" ref="quillEditorInputVideoRef" type="file" accept="video/*" @change="onFileVideoChange" />
const quillEditorInputVideoRef = ref<HTMLInputElement>();
let editor: Quill;
const editorOptions: QuillOptionsStatic = {
theme: 'snow',
modules: {
toolbar: {
container: '#quill-edit-toolbar',
handlers: {
video: () => {
quillEditorInputVideoRef.value ? .click();
},
},
},
},
bounds: '.quill-editor-wrapper',
};
/** 文件上传loading */
const uploadLoading = ref(false);
/** 视频change事件 */
function onFileVideoChange(event: Event) {
const files = (event.target as HTMLInputElement).files!;
let file: File | null = null;
if (files.length <= 0) {
file = null;
return;
}
file = files[0]; // 只取第一个文件
if (!file) return;
uploadLoading.value = true;
uploadApi(file)
.then((src) => {
const range = editor.getSelection(true);
editor.insertText(range.index, '\n', Quill.sources.USER);
editor.insertEmbed(range.index + 1, 'VideoEmbed', src, Quill.sources.USER);
})
.catch((error) => {
ElMessage.error(`上传视频失败`);
console.error('上传视频失败', error);
})
.finally(() => {
uploadLoading.value = false;
quillEditorInputVideoRef.value!.value = ''; // 清空input file
});
}
/** 上传文件api */
function uploadApi(file: File): Promise < string > {
return new Promise((resolve, reject) => {
const fromData = new FormData();
fromData.append('file', file);
uploadFile(fromData)
.then((response: unknown) => {
const {
data
} = response as ResponseInterface<string> ;
return resolve(data);
})
.catch((err) => {
return reject(err);
});
});
}
//初始化编辑器
nextTick(() => {
editor = new Quill(quillEditorRef.value!, editorOptions);
});
container: '#quill-edit-toolbar'
表示使用html中指定id的容器,具体可以看下一篇自定义工具栏的文章。
其实重点就是这三句代码:
const range = editor.getSelection(true);
editor.insertText(range.index, '\n', Quill.sources.USER);
editor.insertEmbed(range.index + 1, 'VideoEmbed', src, Quill.sources.USER);
先获取用户的光标位置,然后插入一个换行符,然后在length+1的地方,插入自定义的blot类型,这个内容对应blotName
静态属性,
至此基本完成,有过有其他需求,可以自己调整。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据