1. 程式人生 > >【Angular2】簡易版富文字編輯器

【Angular2】簡易版富文字編輯器

前言

因為專案中需要使用者輸入一些內容,比如一段話什麼的,這時候需要把使用者的格式記錄下來,再次顯示的時候可以顯示原來的排版

開始想就是引用第三方的元件,比如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中發現是可以直接向後移動,沒有報錯,但是移動的多了一些。於是發現空格和回車都是字元,既然他們都是字元,而且可以被獲取解析,那麼直接改造這段文字就可以了,所以,文章最上面的程式碼就出現了

小結

不斷試驗分析,是可以實現自己功能的
當然直接引用效率很高,不過造輪子也可以很好的鍛鍊自己一下