使用過 office 文檔的同學一定知道他的便捷,不僅可以很好的編輯文檔,還可以賦予它一定的格式、段落、縮進,還可以使用圖片等等。
如果我們在 web 上也想要實現這樣的效果,那么我們應該怎么做呢?
我們可以在網上找到已經封裝好的插件,例如:draft 或者 pell,這些插件都是開箱即用的,也可以在此之上進行封裝。
當然,我們也可以選擇自己封裝一個我們需要的插件。
那怎么才能實現一個富文本編輯器呢?
我們可以選擇 document.execCommand 來實現一個簡易的富文本編輯器。
指令
下面先來看下 document.execCommand 語法:
document.execCommand(commandName, showDefaultUI, value)
上面的語句用來對可編輯的元素執行一段命令,返回布爾值,如果為 false 則表示操作不被支持或未被啟用
我們分別看看參數的含義:
commandName 代表了命令名稱
showDefaultUI 是否展示對話框,true:展示,false:不展示,一般為 false
value 補充信息,例如:插入圖片需要的 url
既然知道了語法,那我們現在封裝一個執行函數用來執行指令:
const exec = (commandName, value = null) => {
document.execCommand(commandName, false, value);
};
接下來,我們來做下工具欄的設計和封裝。
工具欄
假設工具欄有很多格式化的按鈕,當我們點擊的時候所選擇的區域的文字會做相應改變,按鈕既有顯示的樣式,還有執行功能的方法,可以使用對象來表示,所有按鈕屬性的集合形成了工具欄。
我們使用 actions 作為工具欄按鈕的集合,即:
const actions = {
bold: {
icon: "<b>B</b>",
title: "Bold",
result: () => exec("bold"),
},
italic: {
icon: "<i>I</i>",
title: "Italic",
result: () => exec("italic"),
},
underline: {
icon: "<u>U</u>",
title: "Underline",
result: () => exec("underline"),
},
justifyLeft: {
icon: "<span>L</span>",
title: "JustifyLeft",
result: () => exec("justifyLeft"),
},
justifyRight: {
icon: "<span>R</span>",
title: "JustifyRight",
result: () => exec("justifyRight"),
},
justifyCenter: {
icon: "<span>C</span>",
title: "JustifyCenter",
onClick: () => exec("justifyCenter"),
},
};
上面代碼就是一個簡單的工具欄按鈕的集合,其中有 6 個格式化的屬性。
現在,我們來講解下字段:
icon 工具欄顯示的按鈕的樣式
title 按鈕的標題
onClick 點擊按鈕執行的指令
我們已經完成了工具欄的部分,現在我們實現下完整的頁面和編輯區域吧!
編輯區域
首先創建富文本容器,在容器內分別放置工具欄和編輯區域:
<div className="textEditor">
<div className="actions">
{Object.keys(actions).map((action) => (
<button
type="button"
title={actions[action].title}
onClick={actions[action].onClick}
>
{actions[action].icon}
</button>
))}
</div>
<div className="content" contentEditable></div>
</div>
我們最后來看一下實現的效果吧:
應用效果怎么樣呢?我們看下面:
總結
我們已經簡單的實現了一個富文本編輯器,但是這個編輯器還有很大的空間等待我們去優化,比如:點擊工具欄閃爍的問題,更多的功能等。