【Angular2】简易版富文本编辑器

来源:互联网 发布:js生成年月日时分秒 编辑:程序博客网 时间:2024/05/16 12:41

前言

因为项目中需要用户输入一些内容,比如一段话什么的,这时候需要把用户的格式记录下来,再次显示的时候可以显示原来的排版

开始想就是引用第三方的组件,比如primeNG的https://www.primefaces.org/primeng/#/,但是折腾了一晚上总是引入失败,然后分析了一下,这次需求里面的格式无非就是 空格 和 回车,其它的样式也不需要,直接采用默认就好

那么,就自己做一个简易版本的吧,造个轮子呗


代码

HTML代码

<div style="text-align:center">  <h1>    Welcome to APP!  </h1></div><div style="text-align:center">  <textarea rows="10" cols="100" [(ngModel)]="userText" (keydown)="onKeyPress($event)" (click)="getCursortPosition($event)"></textarea></div><h3>数据库存值:</h3><h5 [(ngModel)]="showText">{{showText}}</h5><h3>页面输出:</h3><h5>  <div id="123"></div></h5>

ts代码

export class AppComponent {  userText: string;//用户输入的文本  showText: string;//处理完之后文本  onKeyPress(event: any) {    let saveText: string = "";    //转换为字符串数组进行处理    let saveTextChar: string[] = this.userText.split("");    for (var i = 0; i < saveTextChar.length; i++) {      if (saveTextChar[i] == " ") {        saveTextChar[i] = "&nbsp;&nbsp;";        // console.log("["+i+"]"+"--空格");      }      if (saveTextChar[i] == "\n") {        saveTextChar[i] = "<br/>";        // console.log("["+i+"]"+"--回车");      }    }    //将要存储文本赋给展示文本    for (var i = 0; i < saveTextChar.length; i++) {      saveText = saveText + saveTextChar[i];    }    this.showText = saveText;    //使用HTML显示带格式文本    let el2 = document.getElementById("123");    el2.innerHTML = this.showText;  }

效果图

这里写图片描述


实现的过程

html代码

和上面一样

ts代码

export class AppComponent {  userText: string;  showText: string;  cursorPostion: number = null;  onKeyPress(event: any) {    //获取光标位置    let el: any = event.target;    this.cursorPostion = el.selectionStart;    //获取键值,根据键值处理文本    let keyCode = event.keyCode;    if (keyCode == 32) {   this.userText=this.userText.substring(0,this.cursorPostion)+"&nbsp;"+this.userText.substring(this.cursorPostion,this.userText.length);      }    if (keyCode == 13) {       this.userText=this.userText.substring(0,this.cursorPostion)+"<br/>"+this.userText.substring(this.cursorPostion,this.userText.length);    //显示处理后的文本    let el2 = document.getElementById("123");    el2.innerHTML = this.userText;  }

效果图
这里写图片描述

简单来说,这个是根据鼠标的位置和键值来动态处理文本,每次检测到空格和回车事件,就将用户的输入的文本,根据当前的鼠标位置(不是之间在后面添加)插入相应的标签

但是,因为这是双向绑定的,所以处理完之后的文本用户也看到了。。。

所以,要采取备份的形式,获取用户的输入,在备份中处理,然后存储数据库

这个方案,就需要根据用户当前的光标位置在备份中插入标签,因为插入标签后,备份的光标位置和用户输入是不一样的,所以有了重新计算光标位置的代码

    //计算保存文本中的光标位置    let newCursorPostion:number=this.cursorPostion;    let char:string[]=this.textSave.split("");    for (var i = 0; i < char.length; i++)    {      if(char[i]=='<'&& char[i+1]=='b'&&char[i+4]=='>'){        newCursorPostion=newCursorPostion+5;        console.log("回车");      }      if(char[i]=='&'&& char[i+1]=='n'&&char[i+5]==';'){        newCursorPostion=newCursorPostion+6;        console.log("空格");      }      }

然后发现,不仅光标位置在变,用户的输入文本和备份文本除了标签外也是不一样的,因为用户在输入中,备份没有与其绑定,也不能绑定,所以有了动态更新备份的代码

    //处理存储文本    let saveTextChar:string[]=this.saveText.split("");    let tempTextChar:string[]=tempText.split("");    for (var i = 0; i < tempTextChar.length; i++){      //找到<br/>,插入到存储文本中      if(tempTextChar[i]=='<'&& tempTextChar[i+1]=='b'&&tempTextChar[i+4]=='>'){        let saveTextCharLength:number=saveTextChar.length;        for(var j = i; j < saveTextCharLength+5; j++){          saveTextChar[saveTextCharLength+5]== saveTextChar[saveTextCharLength];        }      }    }

这个是监测到用户输入后,把备份另存起来,直接清空备份,再和用户保持一次,然后遍历另存的,将标签一个个的插入回去

这时候,再插入标签的过程中,需要把字符串变成字符数组,然后字符数组循环后移,给标签腾出位置,在写出这部分代码的时候,感觉直接把数组向后移可能会报错,毕竟开始声明数组没那么大,所以写了一个测试demo

  //转换为字符串数组进行处理    let aa: string[] = this.userText.split("");    for (var i = 0; i < aa.length; i++) {      aa[len+1-i]=aa[len-i];      if (aa[i] == " ") {console.log("aa["+i+"]"+"--空格");}      if (aa[i] == "\n") {console.log("aa["+i+"]"+"--回车");}    }

测试demo的逻辑是:获取用户的输入,根据索引整体向后移动一位,把数组第一个空出来

在这个测试demo中发现是可以直接向后移动,没有报错,但是移动的多了一些。于是发现空格和回车都是字符,既然他们都是字符,而且可以被获取解析,那么直接改造这段文本就可以了,所以,文章最上面的代码就出现了


小结

不断试验分析,是可以实现自己功能的
当然直接引用效率很高,不过造轮子也可以很好的锻炼自己一下

原创粉丝点击