一活翩、插入視頻
主要是用了blots/block/embed
插入的換行的塊級(jí)元素
import { Quill } from 'vue-quill-editor';
const BlockEmbed = Quill.import('blots/block/embed');
class Video 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('videoCover', value.videoCover || '')
node.setAttribute('videoTime', value.videoTime || '')
node.setAttribute('size', value.size || '')
node.setAttribute('webkit-playsinline', true)
node.setAttribute('playsinline', true)
node.setAttribute('x5-playsinline', true)
node.setAttribute('controlslist', value.controlslist || '')
return node;
}
static value (node) {
return {
url: node.getAttribute('src'),
controls: node.getAttribute('controls'),
width: node.getAttribute('width'),
height: node.getAttribute('height'),
videoCover: node.getAttribute('videoCover'),
videoTime: node.getAttribute('videoTime'),
size: node.getAttribute('size'),
controlslist: node.getAttribute('controlslist'),
};
}
}
Video.blotName = 'video';
Video.className = 'ql-video';
Video.tagName = 'video';
export default Video;
使用方法:
import Video from './video';
Quill.register(Video, true);
// 具體插入視頻的方法
insertEle(url) {
let quill = this.$refs.myTextEditor.quill;
let length = quill.selection.savedRange.index;
quill.insertEmbed(length, 'video', {
url,
controls: 'controls',
width: '100%',
height: 'auto',
videoCover: this.videoCover,
videoTime: this.videoTime,
size: this.videoSize
});
// 調(diào)整光標(biāo)到最后
quill.setSelection(length + 1);
},
二丧荐、插入@用戶
實(shí)踐過兩種方式缆瓣,但是第一種有很多坑(比如刪除的時(shí)候光標(biāo)會(huì)提前之類的)
第一種也紀(jì)錄一下吧,主要用的是blots/embed
import { Quill } from 'vue-quill-editor';
const Embed = Quill.import('blots/embed');
class EmbedBlot extends Embed {
static create(value) {
let node = super.create();
if(typeof value === "string"){ //編輯回顯處理
// 匹配到需要的span內(nèi)容
const res = value.match(/<span class="atUser" (.*?)>(.*?)<\/span>/g);
node.innerHTML = res;
return node;
}
EmbedBlot.buildSpan(value, node);
return node;
}
static value(node) {
return node.innerHTML;
}
static buildSpan(value, node) {
let emojiSpan = document.createElement('span');
emojiSpan.classList.add(this.emojiClass);
emojiSpan.innerText = value.text;
emojiSpan.setAttribute('id', value.id);
node.appendChild(emojiSpan);
}
}
EmbedBlot.blotName = 'atTag';
EmbedBlot.emojiClass = 'atUser'
EmbedBlot.tagName = 'span';
export default EmbedBlot;
第二種是最完美的方法虹统,插入一個(gè)行內(nèi)元素:
import { Quill } from 'vue-quill-editor';
const Parchment = Quill.imports.parchment;
class EmbedTag extends Parchment.Embed {
static create(value) {
// 正常span標(biāo)簽就直接返回node對(duì)象
if(value.nodeName==='SPAN'){
return value;
}
const node = super.create(value);
node.contentEditable = 'false';
this.contentNode = document.createElement('span');
this.contentNode.classList.add('atUser');
this.contentNode.setAttribute("id",value.id)
this.contentNode.innerText = value.text;
node.appendChild(this.contentNode);
return node;
}
static value(node) {
return node;
}
}
EmbedTag.blotName = "atTag"
EmbedTag.tagName = "SPAN"
EmbedTag.className = "customTag"; // 這個(gè)一定要加弓坞,不然富文本中其他樣式用到了span標(biāo)簽的也會(huì)讀取這個(gè)自定義blot,比如會(huì)導(dǎo)致我背景顏色取消的時(shí)候找不到原始方法報(bào)錯(cuò)。车荔。渡冻。。忧便。
export default EmbedTag;
使用方法:
import atTag from './atTag';
Quill.register(atTag, true);
// 插入@用戶方法
addTagUser(obj){
const {nick,beanId} = obj;
let text = nick?`@${nick} `: '';
let quill = this.$refs.myTextEditor.quill;
let length = quill.selection.savedRange.index; // 獲取原來光標(biāo)位置
quill.insertEmbed(length, 'atTag', {
id: beanId,
text,
},Quill.sources.USER);
quill.setSelection(length + 1, Quill.sources.USER);
},
艱辛摸索過程紀(jì)錄:
需求:想實(shí)現(xiàn)一個(gè)@用戶 和 表情包的功能族吻,需要支持高亮 和一鍵刪除功能。
主要用到了contentEditable=false
這個(gè)屬性,讓元素可以一鍵刪除呼奢,但是發(fā)現(xiàn)<span contenteditable='false'>@花兒與少年</span>
這種寫法宜雀,點(diǎn)擊元素后面沒有光標(biāo),無法聚焦握础,后來發(fā)現(xiàn)了<span contenteditable="false"><span class="atUser" id="2825639815600373760">@夢(mèng)與千尋 </span></span>
這種包一層的話辐董,就可以聚焦光標(biāo)了(在發(fā)現(xiàn)這種寫法之前,試過很多種的辦法禀综,這里就不描述了简烘,只是這樣說出來顯得很單薄簡(jiǎn)單),這種也可以應(yīng)用于自定義的輸入框中實(shí)現(xiàn)插入表情包等需要高亮和一鍵刪除的需求定枷。
記錄一下:上面說里面包一層span的寫法孤澎,后面又發(fā)現(xiàn)可以不用包一層也可以聚焦,之前不聚焦大致是因?yàn)榻o了span標(biāo)簽display:inline-block
屬性導(dǎo)致的欠窒。