目錄
儘管可以在Blazor項目中使用HTML編輯器,如TinyMC(通過包裝JavaScript代碼),但建議改用本地的Blazor組件。該代碼旨在顯示如何在Blazor中實現HTML編輯器。主要目標是研究這些挑戰,而不是創建在每個瀏覽器中都經過測試的功能強大的編輯器。
介紹
步驟如下:項目HTMBuilder是具有核心編輯器功能的類庫。那是純淨的.NET,沒有UI,帶有附帶的測試項目。
該HTMLEditableContent項目是Blazor組件,帶有一個ContentEditable div。它要求HtmlBuilder在contentEditable div中渲染HTML 。
BlazorHtmlEditor是圍繞HtmlEditableContent構建的Blazor組件。UI外殼使用MatBlazor(Blazor的Material Design)進行編程。
選擇該設計是因爲您可以用自己的組件替換每個組件。如果您不希望使用Material Design編輯器,則可以構建自己的UI Shell。如果只需要邏輯,則HTMLBuilder足夠了。
該代碼完全基於AngleSharp。展示HTML文檔的.NET庫。
挑戰性
最大的挑戰是Blazor綁定與ContentEditable HTML元素的結合。首先,我使用綁定。AngleSharp生成的HTML通過MarkUpString綁定到HTML元素。
問題是瀏覽器以類似MutationObserver的方式在contenteditable元素中實現更改。Blazor通過綁定更新了HTML後,瀏覽器會看到該元素已更改,然後也開始工作。解決該問題的唯一方法不是使用Blazor綁定,而是通過Interop通過JavaScript更新HTML元素。
另一個問題是Editor Blazor組件和HtmlEditableContent Blazor組件必須相互通信。例如,編輯器要顯示光標位置的變化。如果通過參數綁定實現此鏈接,Blazor會將任何光標位置更改都視爲參數更改,包括渲染。你根本不想要那個。
這是通過在Editor和HtmlEditableContent組件之間放置一個共享類來解決的。編輯器在static dictionary中中註冊一個編輯器接口,EditableContent在另一個Htmlbuilder interface中註冊一個static dictionary。dictionary將兩個組件之間被共享。無論是Editor與Content組件具有ID屬性(Guid),並且它是共享的(通過參數)。因爲它們具有相同的鍵,所以它們可以在共享庫中請求彼此的接口,而不會進行任何渲染。這不是理想的方法,但是可以。
仔細看看HtmlEditableContent
如果用戶在瀏覽器中更改光標或選擇,則這些位置更改將通過JavaScript傳遞給Blazor組件。內容更改不會立即傳達。
如果.NET端必須執行操作,它將向瀏覽器詢問位置和內容(innerHTML)。然後,AngleSharp解析文檔並執行操作。結果是新的HTML內容。通過JavaScript,將舊內容替換爲新內容,並恢復光標選擇位置。
此設置限制了JavaScript與Blazor端之間的交互次數。位置變動是個例外。
使用代碼
警告:所有項目都是實驗性的。目的只是演示如何在Blazor中構建一個HtmlEditor。例如,我沒有花時間完全熟悉AngleSharp,也沒有花時間編寫功能齊全的HTML編輯器。另外,我也沒有在所有瀏覽器中測試所有內容。這需要更多時間。我主要關心的是構建Blazor HTML編輯器時遇到的挑戰。
該代碼非常易於使用。
//
<BlazorHtmlEditor.HtmlEditor BlockStylings="@BlockStylings"></BlazorHtmlEditor.HtmlEditor>
//
在BlockStyling參數中,傳遞類似H1和H2的樣式。還有通過Colors和FontStyling的可能性。HtmlEditors使用默認設置,如果你不爲他們提供設置。
現在怎麼辦
學習代碼,自己玩,改進和擴展,提出建議,改善UI等。儘管遇到了種種困難,但與Blazor合作仍然是一種榮幸。
安裝
解壓縮該zip文件。執行:
dotnet restore
將活動目錄更改爲HtmlEditablContent。運行:
npm install
運行:
npm run build:debug