1. 程式人生 > 其它 >vue-quill-editor 富文字 焦點問題 滾動條自動跳轉

vue-quill-editor 富文字 焦點問題 滾動條自動跳轉

問題描述:編輯器的文字內容變更後,編輯器自動獲取焦點,滾動條定位到編輯期處 解決思路:文字內容變更後,先禁編輯器,待元件渲染完成後,丟掉編輯期的焦點,再取消禁用,完美解決問題

const editor = this.$refs.editor;
this.Quill = new Quill(editor, this.options);

//禁用編輯器,防止頁面自動滾動到編輯器位置
this.Quill.enable(false);
// 編輯器繫結內容,如修改的時候原有的內容
this.Quill.pasteHTML(this.currentValue);
this.$nextTick(function() {
//丟掉編輯器焦點並重新啟用編輯器
this.Quill.blur();
this.Quill.enable(true);
});

完整程式碼如下:

<template>
<div>
<el-upload :action="uploadUrl" :on-success="handleUploadSuccess" :on-error="handleUploadError" name="file"
:show-file-list="false" :headers="headers" style="display: none" ref="upload" v-if="this.uploadUrl">
</el-upload>
<div class="editor" ref="editor"
:style="styles"></div> </div> </template> <script> import Quill from "quill"; import "quill/dist/quill.core.css"; import "quill/dist/quill.snow.css"; import "quill/dist/quill.bubble.css"; import { getToken } from "@/utils/auth"; export default { name: "Editor", props: { /* 編輯器的內容 */
value: { type: String, default: "", }, /* 高度 */ height: { type: Number, default: null, }, /* 最小高度 */ minHeight: { type: Number, default: null, }, /* 只讀 */ readOnly: { type: Boolean, default: false, }, /* 上傳地址 */ uploadUrl: { type: String, default: "", } }, data() { return { headers: { Authorization: "Bearer " + getToken() }, Quill: null, currentValue: "", options: { theme: "snow", bounds: document.body, debug: "warn", modules: { // 工具欄配置 toolbar: [ ["bold", "italic", "underline", "strike"], // 加粗 斜體 下劃線 刪除線 ["blockquote", "code-block"], // 引用 程式碼塊 [{ list: "ordered" }, { list: "bullet" }], // 有序、無序列表 [{ indent: "-1" }, { indent: "+1" }], // 縮排 [{ size: ["small", false, "large", "huge"] }], // 字型大小 [{ header: [1, 2, 3, 4, 5, 6, false] }], // 標題 [{ color: [] }, { background: [] }], // 字型顏色、字型背景顏色 [{ align: [] }], // 對齊方式 ["clean"], // 清除文字格式 ["link", "image", "video"] // 連結、圖片、視訊 ], }, placeholder: "請輸入內容", readOnly: this.readOnly, }, }; }, computed: { styles() { let style = {}; if (this.minHeight) { style.minHeight = `${this.minHeight}px`; } if (this.height) { style.height = `${this.height}px`; } return style; } }, watch: { value: { handler(val) { if (val !== this.currentValue) { this.currentValue = val === null ? "" : val; if (this.Quill) { this.Quill.pasteHTML(this.currentValue); } } }, immediate: true, }, }, mounted() { this.init(); }, beforeDestroy() { this.Quill = null; }, methods: { init() { const editor = this.$refs.editor; this.Quill = new Quill(editor, this.options); // 如果設定了上傳地址則自定義圖片上傳事件 if (this.uploadUrl) { let toolbar = this.Quill.getModule("toolbar"); toolbar.addHandler("image", (value) => { this.uploadType = "image"; if (value) { this.$refs.upload.$children[0].$refs.input.click(); } else { this.quill.format("image", false); } }); toolbar.addHandler("video", (value) => { this.uploadType = "video"; if (value) { this.$refs.upload.$children[0].$refs.input.click(); } else { this.quill.format("video", false); } }); } //禁用編輯器,防止頁面自動滾動到編輯器位置 this.Quill.enable(false); // 編輯器繫結內容,如修改的時候原有的內容 this.Quill.pasteHTML(this.currentValue); this.$nextTick(function() { //丟掉編輯器焦點並重新啟用編輯器 this.Quill.blur(); this.Quill.enable(true); }); this.Quill.on("text-change", (delta, oldDelta, source) => { const html = this.$refs.editor.children[0].innerHTML; const text = this.Quill.getText(); const quill = this.Quill; this.currentValue = html; this.$emit("input", html); this.$emit("on-change", { html, text, quill }); }); this.Quill.on("text-change", (delta, oldDelta, source) => { this.$emit("on-text-change", delta, oldDelta, source); }); this.Quill.on("selection-change", (range, oldRange, source) => { this.$emit("on-selection-change", range, oldRange, source); }); this.Quill.on("editor-change", (eventName, ...args) => { this.$emit("on-editor-change", eventName, ...args); }); }, handleUploadSuccess(res, file) { // 獲取富文字元件例項 let quill = this.Quill; // 如果上傳成功 if (res.code == 200) { // 獲取游標所在位置 let length = quill.getSelection().index; // 插入圖片 res.url為伺服器返回的圖片地址 quill.insertEmbed(length, "image", res.url); // 調整游標到最後 quill.setSelection(length + 1); } else { this.$message.error("圖片插入失敗"); } }, handleUploadError() { this.$message.error("圖片插入失敗"); }, }, }; </script> <style> .editor, .ql-toolbar { white-space: pre-wrap !important; line-height: normal !important; } .quill-img { display: none; } .ql-snow .ql-tooltip[data-mode="link"]::before { content: "請輸入連結地址:"; } .ql-snow .ql-tooltip.ql-editing a.ql-action::after { border-right: 0px; content: "儲存"; padding-right: 0px; } .ql-snow .ql-tooltip[data-mode="video"]::before { content: "請輸入視訊地址:"; } .ql-snow .ql-picker.ql-size .ql-picker-label::before, .ql-snow .ql-picker.ql-size .ql-picker-item::before { content: "14px"; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before { content: "10px"; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before { content: "18px"; } .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before, .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before { content: "32px"; } .ql-snow .ql-picker.ql-header .ql-picker-label::before, .ql-snow .ql-picker.ql-header .ql-picker-item::before { content: "文字"; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { content: "標題1"; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { content: "標題2"; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { content: "標題3"; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { content: "標題4"; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { content: "標題5"; } .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before, .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { content: "標題6"; } .ql-snow .ql-picker.ql-font .ql-picker-label::before, .ql-snow .ql-picker.ql-font .ql-picker-item::before { content: "標準字型"; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before { content: "襯線字型"; } .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before, .ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before { content: "等寬字型"; } </style>