【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] = " ";
// 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)+" "+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中發現是可以直接向後移動,沒有報錯,但是移動的多了一些。於是發現空格和回車都是字元,既然他們都是字元,而且可以被獲取解析,那麼直接改造這段文字就可以了,所以,文章最上面的程式碼就出現了
小結
不斷試驗分析,是可以實現自己功能的
當然直接引用效率很高,不過造輪子也可以很好的鍛鍊自己一下