vue下自己開發富文本編輯器(一)帶你從入門到放棄

前言:

首先,我這個文章不會寫非常詳細的代碼,但是我會把我目前博客開發的富文本編輯遇到的問題羅列出來。然後一點點的說明如何解決。說實在目前遇到的問題,已經想讓我放棄自己開發富文本了,真的是非誠勿擾。這個坑沒那麼簡單。(捂臉哭)

開發環境:vueCli3.X

一、HTML5的富文本

contentEditable="true"

這個屬性我不介紹了,不懂得自己百度

二、編寫頁面遇到的坑(點擊事件失去焦點)

網上大多數富文本編輯器都是iframe,很多成熟的富文本編輯器也是用的iframe。我個人不知道好壞,所以我直接用的div。也許後期會遇到無法解決的坑再換吧。

我不知道是不是我不是用的iframe的問題,但是每當我需要操作文字加粗都失敗,原因在於失去選區。

解決:a標籤和img標籤不會失去選區,改代碼。

上個人代碼:

<div class="dht-editor-operation">
      <template v-for="(item, index) in operationList">
        <a :key="index" @click="item.event" :title="item.title">
          <img :src="item.iconUrl" :style="item.backgroundImg" alt="" />
        </a>
      </template>
    </div>

三、我的文字不會加粗

我其實第一個寫的功能是顏色選擇器,沒寫很複雜就是用input的color屬性

第二功能是文字加粗。但是不會加粗。最後檢查得知是因爲,我自己有一個全局存在的樣式重置代碼。我把b標籤的默認樣式去除了。

到這個時候我都還是用的富文本自己的操作函數

document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)

文檔地址:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/execCommand

這裏開始就踩坑很嚴重了。因爲樣式重置,我考慮到如果別人用我的東西,那麼也會這樣,那就是說我得避免這個情況。所以我選擇了另一條路,自己實現這些功能。當然不可能所有都自己實現,那就太累了,我也不是寫產品,給自己用的。

解決方式

使用:window.getSelection()Range()

參考教程:https://www.jianshu.com/p/5997a90aab64

MDN文檔:https://developer.mozilla.org/zh-CN/docs/Web/API/Selection

MDN文檔:https://developer.mozilla.org/zh-CN/docs/Web/API/Range

這裏文檔得好好看看,不然我下面的代碼你看不懂。

第一次解決方式

我用的代碼是這樣的(不要在意我這裏是改顏色,原理懂了就行)

代碼來自這篇博客:https://www.cnblogs.com/wyjs/articles/9733827.html

我個人一開始就是按這位的博客來寫的,很詳細

var selection = document.getSelection();
//取得選擇的文本
var selectionText = selection.toString();
//取得代表選區的範圍
var range = selection.getRangeAt(0);
//突出顯示選擇的文本
var span = document.createElement("span");
span.style.backgroundColor = "yellow";
range.surroundContents(span);

這種方式用的是range.surroundContents,意思是將你選中的文檔放在一個新的標籤中。

但是問題很嚴重

缺點:

1、無限的加入標籤中,會無限嵌套html元素(自己開發中看f12就懂了)

2、無法跨元素操作

比如這樣的,這種選擇是不能成功的,報錯。因爲他無法操作多個dom元素。

 

這時候已經巨坑了好吧。我原本以爲就和別人說的一樣,好簡單。你要是不考慮那麼多操作,不當初編輯器來操作確實簡單啊。

第二種解決方式(目前我測試沒什麼問題)

原理在於先刪後插,需要需要各位理解range選區(拖藍部分的代碼意思,仔細看文檔咯)

這裏還是會產生無限嵌套問題,我再找找方式,但是解決了跨元素選擇問題

代碼:

CursorAcquisition() {
      let selection = window.getSelection();
      let range = selection.getRangeAt(0);
      return {
        selection,
        range
      };
    },
//取得代表選區的範圍
      let range = this.CursorAcquisition().range;
      //突出顯示選擇的文本
      //let rangeClone = range.cloneRange();
      //獲得選中區域dom袁術
      let rangeText = range.extractContents();
      //創建新的dom並且結合
      let span = document.createElement("span");
      span.appendChild(rangeText);
      span.style.color = "red";
      //先移除選中節點
      range.deleteContents();
      //再插入節點
      range.insertNode(span);

這個代碼就能實現上述所有產生的問題。至少我暫時這麼認爲,大神則請指出。

 

 

好了第一篇踩坑到此結束,各位請先品嚐。後面我還會寫下一篇。因爲下一個坑我已經踩完了。心累。不寫博客我都不知道哪裏去發泄。網上的教程即好又缺斤少兩,少關鍵啊。

最後附上,我的顏色選擇器,不需要添加html元素。但是需要支持input color

//顏色選擇器
    colorSelect() {
      let input = document.createElement("input");
      let that = this;
      input.type = "color";
      input.click();
      input.addEventListener("input", watchColorPicker, false);
      function watchColorPicker(event) {
        //console.log(event.target.value);
        let color = event.target.value;
        that.operationList[0].backgroundImg = {
          background: color
        };
        //移除監聽
        input.removeEventListener("input", watchColorPicker, false);
        input = "";
      }
    }

個人項目代碼都在git上面:

地址:https://github.com/ht-sauce/dream

本次富文本開發的路徑截圖,項目屬於持續完善,所以代碼比較亂。

項目富文本本地打開地址:http://localhost:8080/dht_blog/richTextEditor

 

項目的最後:

富文本肯定不是到這裏就結束了,但是從目前自己代碼的方式來寫,不亞於放棄一切,然後構建一個新的文本編輯器。考慮代碼重構,捨棄當前複雜的開發方式。從博文發出,到發現bug,再到重新百度富文本編輯器原理,經歷了3個小時。實在沒辦法,真不是兩三天能寫完的。

下面我將開後端nodejs項目,研究koa框架和阿里的egg框架。計劃開始搞自己的後端服務代碼了。畢竟一個博客不能只是前端頁面。但是,後端不會太深入,因爲要有所側重。因爲都是nodejs,所以js代碼方面不會荒廢。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章