在Angular中自定义Quill的扩展功能

2019-12-12  本文已影响0人  户口米青

在Angular中自定义Quill的扩展功能

安装

 npm i quill@1.3.7
 npm i @types/quill@1.3.7
 npm i  parchment@^1.1.4  --save-dev

angular.json配置文件引入css

{
  "projects": {
    "app": {
      "architect": {
        "build": {
          "options": {
            "styles": [
              { "input": "node_modules/quill/dist/quill.core.css" },
              { "input": "node_modules/quill/dist/quill.snow.css" },
              { "input": "node_modules/quill/dist/quill.bubble.css" }
            ]
          }
        }
      }
    }
  }
}

styles节点粘贴到angular.json指定位置即可

如何使用

导入

import Quill from 'quill';

完整的toolbar

  <div #quillToolbar>
    <span class="ql-formats">
      <select class="ql-font"></select>
      <select class="ql-size"></select>
    </span>
    <span class="ql-formats">
      <button class="ql-bold"></button>
      <button class="ql-italic"></button>
      <button class="ql-underline"></button>
      <button class="ql-strike"></button>
    </span>
    <span class="ql-formats">
      <select class="ql-color"></select>
      <select class="ql-background"></select>
    </span>
    <span class="ql-formats">
      <button class="ql-script" value="sub"></button>
      <button class="ql-script" value="super"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-header" value="1"></button>
      <button class="ql-header" value="2"></button>
      <button class="ql-blockquote"></button>
      <button class="ql-code-block"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-list" value="ordered"></button>
      <button class="ql-list" value="bullet"></button>
      <button class="ql-indent" value="-1"></button>
      <button class="ql-indent" value="+1"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-direction" value="rtl"></button>
      <select class="ql-align"></select>
    </span>
    <span class="ql-formats">
      <button class="ql-link"></button>
      <button class="ql-image"></button>
      <button class="ql-video"></button>
      <button class="ql-formula"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-clean"></button>
    </span>
  </div>
  <div #quillEditor></div>
import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';
import Quill from 'quill';

@Component({
  selector: 'quill-editor-page',
  templateUrl: 'quill-editor-page.html',
  styleUrls: ['quill-editor-page.scss']
})
export class QuillEditorPage implements OnInit {

  @ViewChild('quillEditor', { static: true }) quillEditor: ElementRef;
  @ViewChild('quillToolbar', { static: true }) quillToolbar: ElementRef;

  constructor() { }

  ngOnInit() {
    const quill = new Quill(this.quillEditor.nativeElement, {
      modules: {
        toolbar: this.quillToolbar.nativeElement
      },
      theme: 'snow'
    });
  }

}

如何扩展功能

import Parchment from 'parchment';
import Quill from 'quill';

Parchment.Embed = Quill.import('blots/block/embed');
export abstract class BaseEmbedBlot extends Parchment.Embed {
    constructor(domNode: HTMLElement) {
        super(domNode);
    }
}

定义一个添加照片的扩展 PhotoBlot

import Parchment from 'parchment';
import Quill from 'quill';
import BaseEmbedBlot  from './BaseEmbedBlot';
 
export class PhotoBlot extends BaseEmbedBlot {
    static blotName = 'photo';
    static tagName = 'img';
    static create(value) {
        const node = super.create(value) as HTMLElement;
        node.setAttribute('alt', value.alt);
        node.setAttribute('src', value.url);
        node.setAttribute('onclick', `alert('')`);
        return node;
    }

    static value(node) {
        return {
            alt: node.getAttribute('alt'),
            url: node.getAttribute('src')
        };
    }
}

注册扩展

  <div #quillToolbar>
    <!-- 
      Quill.register({'formats/photo': PhotoBlot});
      'formats/photo' 对应 ql-photo , 其中ql-photo中的photo与 PhotoBlot 定义的 static blotName = 'photo' 保持一致
    -->
    <span class="ql-formats">
      <button class="ql-photo"></button>
    </span>
  </div>
  <div #quillEditor></div>
export class TestPage implements OnInit {

  @ViewChild('quillEditor', { static: true }) quillEditor: ElementRef;
  @ViewChild('quillToolbar', { static: true }) quillToolbar: ElementRef;
  constructor() {

  }
  private quill: Quill;
  ngOnInit() {
    Quill.register({ 'formats/photo': PhotoBlot });
    this.quill = new Quill(this.quillEditor.nativeElement, {
      modules: {
        toolbar: this.quillToolbar.nativeElement
      },
      theme: 'snow'
    });
    const m = this.quill.getModule('toolbar');
    m.addHandler('photo', this.insertPhoto);
  }

  insertPhoto(event) {
    console.log(event);
    const range = this.quill.getSelection(true);
    // "api" | "user" | "silent"
    this.quill.insertText(range.index, '\n', 'user');
    this.quill.insertEmbed(range.index + 1, 'photo', {
      alt: 'Quill Photo',
      url: 'https://quilljs.com/0.20/assets/images/cloud.png'
    }, 'user');
    this.quill.setSelection(range.index + 2, 0, 'silent');
  }
}

完整使用的例子

test.page.html

  <div #quillToolbar>
    <span class="ql-formats">
      <button class="ql-photo">
        <svg viewBox="0 0 18 18">
          <rect class="ql-stroke" height="10" width="12" x="3" y="4"></rect>
          <circle class="ql-fill" cx="6" cy="7" r="1"></circle>
          <polyline class="ql-even ql-fill" points="5 12 5 11 7 9 8 10 11 7 13 9 13 12 5 12"></polyline>
        </svg>
      </button>
    </span>
  </div>
  <div #quillEditor></div>

photo-blot.page.ts

import Quill from 'quill';
import BaseEmbedBlot  from './BaseEmbedBlot';

export class PhotoBlot extends BaseEmbedBlot {
    static blotName = 'photo';
    static tagName = 'img';
    static create(value) {
        const node = super.create(value) as HTMLElement;
        node.setAttribute('alt', value.alt);
        node.setAttribute('src', value.url);
        node.setAttribute('onclick', `alert('')`);
        return node;
    }

    static value(node) {
        return {
            alt: node.getAttribute('alt'),
            url: node.getAttribute('src')
        };
    }

}

test.page.ts

@Component({
  selector: 'app-test',
  templateUrl: 'test.page.html',
  styleUrls: ['test.page.scss']
})
export class TestPage implements OnInit {

  @ViewChild('quillEditor', { static: true }) quillEditor: ElementRef;
  @ViewChild('quillToolbar', { static: true }) quillToolbar: ElementRef;
  constructor() {

  }
  private quill: Quill;
  ngOnInit() {
    Quill.register({ 'formats/photo': PhotoBlot });
    this.quill = new Quill(this.quillEditor.nativeElement, {
      modules: {
        toolbar: this.quillToolbar.nativeElement
      },
      theme: 'snow'
    });
    const m = this.quill.getModule('toolbar');
    m.addHandler('photo', this.insertPhoto);
  }

  insertPhoto(event) {
    console.log(event);
    const range = this.quill.getSelection(true);
    // "api" | "user" | "silent"
    this.quill.insertText(range.index, '\n', 'user');
    this.quill.insertEmbed(range.index + 1, 'photo', {
      alt: 'Quill Photo',
      url: 'https://quilljs.com/0.20/assets/images/cloud.png'
    }, 'user');
    this.quill.setSelection(range.index + 2, 0, 'silent');
  }
}


上一篇 下一篇

猜你喜欢

热点阅读