README
项目
基于angular 8.0.1编写的富文本模块编辑器
demo演示
使用
npm install xre-edit-template --save
npm install ng-zorro-antd --save
或者直接下载源码在自己的项目中使用
在需要使用的模块里引入下面代码
import { TemplateModule, EditingAreaItemService } from 'xre-edit-template';
import { NzModalModule} from 'ng-zorro-antd';
import { NzMessageModule } from 'ng-zorro-antd';
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
TemplateModule,
NzModalModule,
NzMessageModule,
FormsModule
],
providers: [
EditingAreaItemService
]
})
项目目录
app
template
--content-editor-tool
--edit-bar
--editing-area
--editing-area-item
toolbar
template.component.css
template.component.html
template.component.ts
template.module.ts
app-routing.module.ts
app.component.css
app.component.html
app.component.ts
app.module.ts
配置
内容区
<div id='editing-area'>
<bl-editing-area [items]="editingAreaItemService.items">
</bl-editing-area>
</div>
其中注意id='editing-area'是必须的,除非你自行下载源码下载使用可以更改
首先配置items数据如下
ngOnInit() {
that.editingAreaItemService.items = [
{
type: 'div',
index: 0,
style: {
},
children: [
{
type: 'txt',
id: 'txt0',
style: {
'margin': 0,
'line-height': '35px',
'outline-color': 'blue'
},
content: '小时不识月, 呼作白玉盘。',
isEdit: true,
isShowEditorTool: false,
toolConfigure: ['bold', 'italic', 'slideLine', 'link', 'unlink', 'fontColor', 'backgroundColor', 'fontSize']
}
]
},
{
type: 'div',
index: 1,
children: [
{
type: 'button',
id: 'button1',
style: {
'background': '#fff',
'border': '1px solid #ccc',
'color': 'red',
'padding': '5px',
'margin': '2px 0',
'border-radius': '5px',
'outline-color': 'blue'
},
content: '立即点击',
isEdit: true,
isShowEditorTool: false,
toolConfigure: ['bold', 'italic', 'slideLine', 'fontColor', 'backgroundColor', 'fontSize']
}
]
},
{
type: 'div',
index: 2,
children: [
{
type: 'img',
id: 'img2',
style: {
'width': '400px',
},
isEdit: false,
url: '../../../assets/img/bglogin.png',
href: 'http://www.baidu.com',
}
]
},
{
type: 'div',
index: 3,
style: {
},
children: [
{
type: 'txt',
id: 'txt3',
style: {
'margin': 0,
'line-height': '35px',
'outline-color': 'blue'
},
content: '小时不识月, 呼作白玉盘。',
isEdit: true,
isShowEditorTool: false,
toolConfigure: ['bold', 'italic', 'slideLine', 'link', 'unlink', 'fontColor', 'fontSize']
}
]
},
];
that.editingAreaItemService.initialCyclel(that.editingAreaItemService.items);
that.editingAreaItemService.base = 0;
that.editingAreaItemService.idBase = 0;
that.editingAreaItemService.sortIndex(that.editingAreaItemService.items);
}
其中
isEdit 控制此块是否可以被编辑;
isShowEditorTool 控制是否显示行内编辑器;
toolConfigure 控制行内编辑器哪些工具显示
工具栏
<bl-toolbar [toolBarConfigure]="toolBarConfigure"></bl-toolbar>
//这里是配置工具栏哪些显示和隐藏
toolBarConfigure = [
'text',
'backgroundText',
'img',
'imgGroup',
'imgText',
'backgroundImgText',
'code',
'button',
'line',
'head',
'foot',
'share'];
编辑栏
<bl-edit-bar [editBarConfigure]="editBarConfigure"></bl-edit-bar>
editBarConfigure = [
{
name: 'typefaces',
typefacesList: [
{ name: '宋体', code: 'SimSun' },
{ name: '黑体', code: 'SimHei' },
{ name: '微软雅黑', code: 'Microsoft YaHei' },
{ name: '微软正黑体', code: 'Microsoft JhengHei' },
{ name: '新宋体', code: 'NSimSun' },
{ name: '新细明体', code: 'PMingLiU' },
{ name: '细明体', code: 'MingLiU' },
{ name: '标楷体', code: 'DFKai-SB' },
{ name: '仿宋', code: 'FangSong' },
{ name: '楷体', code: 'KaiTi' }
],
isShow: true,
style: {
'border-radius': '5px',
'outline': 'none',
'width': '150px',
'height': '30px'
}
},
{
name: 'fontSize',
isShow: true,
style: {
'width': '110px',
},
maximumInterval: 30,
}
];
上述配置不完全
name 代表编辑栏工具的名称
isShow 控制编辑栏工具是否显示和隐藏
style 控制样式
maximumInterval 控制滑块拉动区间
下面列出目前配置的工具名称,具体使用请参照源码使用,配置同上:
typefaces 字体
fontSize 字号
fontColor 字体颜色
lineHeight 行距
letterSpacing 间距
textStyle 居中等文本样式
backgroundColor 文本背景色
imgTextBackgroundColor 图文块背景色
border 边框
lineBorder 分割线
核心服务
在editing-area-item.service.ts文件中用来处理页面上初始化数据、保存、删除、预览等功能
import { Injectable, SecurityContext } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { EeitingAreaItem } from './eiting-area-item.model';
@Injectable({
providedIn: 'root'
})
export class EditingAreaItemService {
isShowBorder = true;
isClick = true;
items: EeitingAreaItem[] = [];
boxDom: any;
itemDom: any;
isGroup = false;
isReUrl = false;
insertIndex = 0;
type: string;
imgUrl: any;
imgSize: any;
imgHref: any;
elem: any;
base = 0;
idBase = 0;
divDom = document.getElementById('editing-area');
constructor(
public sanitizer: DomSanitizer,
) { }
trustHtml(str: string) {
return this.sanitizer.bypassSecurityTrustHtml(str);
}
transformationString(content: any) {
return this.sanitizer.sanitize(SecurityContext.HTML, content);
}
// 初始循环渲染行内样式
initialCyclel(obj: any) {
const that = this;
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < obj.length; i++) {
for (const key in obj[i]) {
if (Array.isArray(obj[i][key])) {
that.initialCyclel(obj[i][key]);
} else {
if (key === 'content') {
obj[i][key] = that.trustHtml(obj[i][key]);
}
}
}
}
}
// 结束循环还原初始样式
endCyclels(obj: any) {
const that = this;
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < obj.length; i++) {
for (const key in obj[i]) {
if (Array.isArray(obj[i][key])) {
that.endCyclels(obj[i][key]);
} else {
if (key === 'content') {
obj[i][key] = that.transformationString(obj[i][key]);
}
if (key === 'isShowEditorTool') {
obj[i][key] = false;
}
}
}
}
}
// 预览时处理数据、不可编辑
previewCyclel(obj: any) {
const that = this;
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < obj.length; i++) {
for (const key in obj[i]) {
if (Array.isArray(obj[i][key])) {
that.previewCyclel(obj[i][key]);
} else {
if (key === 'isEdit') {
obj[i][key] = false;
}
if (key === 'isShowEditorTool') {
obj[i][key] = false;
}
}
}
}
}
// 排顺序
sortIndex(obj: any) {
const that = this;
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < obj.length; i++) {
for (const key in obj[i]) {
if (Array.isArray(obj[i][key])) {
that.sortIndex(obj[i][key]);
} else {
if (key === 'index') {
obj[i][key] = that.base;
that.base++;
}
if (key === 'id') {
obj[i][key] = that.idBase;
that.idBase++;
}
}
}
}
}
// 插入模板
insertTemplate(dataTmp: any) {
const that = this;
that.base = 0;
that.idBase = 0;
const index = that.insertIndex;
const htmlData = dataTmp;
that.initialCyclel(htmlData);
that.items.splice(index + 1, 0, htmlData);
that.insertIndex++;
that.sortIndex(that.items);
}
// 删除模板
deleteTemplate() {
this.base = 0;
this.idBase = 0;
const index = this.insertIndex;
this.items.splice(index, 1);
this.insertIndex--;
this.sortIndex(this.items);
}
// 隐藏行内编辑器
hideEditorTool(obj: any) {
const that = this;
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < obj.length; i++) {
for (const key in obj[i]) {
if (Array.isArray(obj[i][key])) {
that.hideEditorTool(obj[i][key]);
} else {
if (key === 'isShowEditorTool') {
obj[i][key] = false;
}
}
}
}
}
// 内容更改后重新复制
setContent(obj: any, id: any, content: any) {
const that = this;
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < obj.length; i++) {
for (const key in obj[i]) {
if (Array.isArray(obj[i][key])) {
that.setContent(obj[i][key], id, content);
} else {
if (obj[i].id === id) {
obj[i].content = that.trustHtml(content);
}
}
}
}
}
}