Angular4 实现富文本编辑器

富文本编辑器是 Web 开发中常用的一个功能,可以让用户轻松地编辑复杂的 HTML 内容,如排版、插入图片、插入链接等。本文介绍了如何使用 Angular4 实现一个富文本编辑器。

1. 富文本编辑器的基本要素

一个富文本编辑器通常包括以下要素:

  1. 文本输入框:用户输入文本的地方,可以使用 HTML 的 contenteditable 属性实现。

  2. 工具栏:提供了一组操作按钮,如加粗、斜体、插入图片等。

  3. 预览区域:预览编辑后的内容。

  4. 数据存储:将编辑后的 HTML 内容存储到后台数据库中。

2. 构建 Angular4 的富文本编辑器

2.1 创建 Angular4 项目

我们首先需要创建一个 Angular4 项目,使用 Angular CLI 可以非常方便地创建一个基于 Angular4 的项目。

npm install -g @angular/cli
ng new my-editor

然后进入项目目录:

cd my-editor

2.2 安装依赖

我们需要安装以下依赖:

  1. ngx-quill:一个基于 Quill 的富文本编辑器。

  2. quill:一个强大的富文本编辑器,在 ngx-quill 的基础上进行了封装。

  3. @types/quillquill 的 TypeScript 类型。

npm install ngx-quill quill @types/quill --save

3. 构建富文本编辑器组件

我们可以通过创建一个组件来实现富文本编辑器。创建 editor.component.ts 文件,声明必要的输入和输出属性,并初始化编辑器:

import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html';
import Quill from 'quill';

@Component({
  selector: 'app-editor',
  templateUrl: './editor.component.html',
  styleUrls: ['./editor.component.css']
})
export class EditorComponent implements OnInit {
  editor: Quill;
  html: string;

  @Input() placeholder = 'Enter text here...';
  @Input() height = '300px';
  @Input() showToolbar = true;
  @Input() readonly = false;
  @Input() initContent: any;
  @Output() contentChanged = new EventEmitter();

  ngOnInit() {
    const toolbarOptions = [
      ['bold', 'italic', 'underline', 'strike'],
      [{ 'header': 1 }, { 'header': 2 }],
      [{ 'list': 'ordered' }, { 'list': 'bullet' }],
      [{ 'size': ['small', false, 'large', 'huge'] }],
      [{ 'color': [] }, { 'background': [] }],
      [{ 'font': [] }],
      [{ 'align': [] }],
      ['link', 'image'],
      ['clean']
    ];

    const options = {
      modules: {
        toolbar: toolbarOptions
      },
      placeholder: this.placeholder,
      theme: 'snow',
      readOnly: this.readonly
    };

    Quill.register('modules/counter', function (quill, options) {
      const container = document.querySelector('.ql-characters');
      quill.on('text-change', function () {
        const text = quill.getText();
        const length = text.length - 1;
        container.innerHTML = `${length}/1000`;
      });
    });

    this.editor = new Quill('#editor', options);

    if (this.showToolbar) {
      this.editor.addModule('toolbar', { container: '#toolbar' });
    }

    if (this.initContent) {
      this.editor.setContents(JSON.parse(this.initContent));
    }

    this.editor.on('text-change', (delta, oldDelta, source) => {
      this.html = this.toHtml(delta.ops);
      this.contentChanged.emit(JSON.stringify(delta.ops));
    });

    this.editor.on('focus', () => {
      const length = this.editor.getLength() - 1;
      const container = document.querySelector('.ql-characters');
      container.innerHTML = `${length}/1000`;
    });
  }

  toHtml(ops): string {
    const deltaToHtml = new QuillDeltaToHtmlConverter(ops, {});
    const html = deltaToHtml.convert();
    return html;
  }
}

在上述代码中,我们声明了输入和输出属性,提供了默认值;使用 Quill 初始化富文本编辑器,配置了 toolbarread-only 选项;在内容改变和获得焦点时都发出了事件。

3.1 编辑器模板

在模板中,我们需要使用 Quill 的容器来显示文本编辑器。代码如下:

<div class="editor-container">
  <div *ngIf="showToolbar" id="toolbar">
    <span class="ql-formats">
      <button class="ql-bold" aria-label="Bold"></button>
      <button class="ql-italic" aria-label="Italic"></button>
      <button class="ql-underline" aria-label="Underline"></button>
      <button class="ql-strike" aria-label="Strike"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-header" value="1" aria-label="Heading 1"></button>
      <button class="ql-header" value="2" aria-label="Heading 2"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-list" value="ordered" aria-label="Ordered List"></button>
      <button class="ql-list" value="bullet" aria-label="Unordered List"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-size" value="small" aria-label="Small"></button>
      <button class="ql-size" aria-label="Normal"></button>
      <button class="ql-size" value="large" aria-label="Large"></button>
      <button class="ql-size" value="huge" aria-label="Huge"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-color" aria-label="Text Color"></button>
      <button class="ql-background" aria-label="Background Color"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-font" aria-label="Font"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-align" value="left" aria-label="Align Left"></button>
      <button class="ql-align" value="center" aria-label="Align Center"></button>
      <button class="ql-align" value="right" aria-label="Align Right"></button>
      <button class="ql-align" value="justify" aria-label="Justify"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-link" aria-label="Insert Link"></button>
      <button class="ql-image" aria-label="Insert Image"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-clean" aria-label="Remove Styles"></button>
    </span>
    <span class="ql-formats">
      <span class="ql-formats-remaining ql-characters">
        <span>0/1000</span>
      </span>
    </span>
  </div>
  <div [style.height]="height" id="editor" contenteditable="true"></div>
  <div *ngIf="html" class="preview" [innerHTML]="html"></div>
</div>

在代码中,我们使用控制台输出的 CSS 样式,声明了富文本编辑器的工具栏和编辑区域,实现了绑定输入和事件的功能。

3.2 编辑器样式

最后,我们需要为富文本编辑器编写样式,代码如下:

.editor-container {
  display: flex;
  flex-direction: column;
  margin-top: 10px;
}

.preview {
  margin-top: 10px;
  padding: 5px;
  border: solid 1px gray;
}

#toolbar {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  align-items: center;
  box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1);
  padding: 8px;
  background-color: #fff;
  border: solid 1px gray;
}

.ql-editor {
  min-height: 100px;
  font-size: 16px;
}

.ql-editor img {
  max-width: 100%;
}

在代码中,我们实现了工具栏、编辑区域和预览区域的样式设置。

4. 使用组件

为了使用组件,我们在 app.module.ts 中注册组件。代码如下:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { QuillModule } from 'ngx-quill';

import { AppComponent } from './app.component';
import { EditorComponent } from './editor/editor.component';

@NgModule({
  declarations: [
    AppComponent,
    EditorComponent
  ],
  imports: [
    BrowserModule,
    QuillModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

然后就可以在组件中使用我们自定义的富文本编辑器了:

<app-editor [initContent]="initContent" [showToolbar]="true" 
            (contentChanged)="onContentChanged($event)"></app-editor>

5. 总结

本文介绍了如何使用 Angular4 和 ngx-quill 实现富文本编辑器,包括基本要素、组件、模板和样式等。我们在创建自定义编辑器时需要注意输入和输出属性的使用,以及 Quill 对于富文本编辑器中 delta 和 ops 的概念。富文本编辑器是一个功能强大的工具,可以让用户轻松地编辑复杂的 HTML 内容,是 Web 开发中必不可少的一个组件。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659e39b2add4f0e0ff7433b4


纠错反馈