もう2020年です。飢えた人間は単純なテキストでは満足できなくなり、さまざまなスタイルの派手なテキストが登場しています。しかし、テキストがあるだけでは十分ではありません。私たちが発信するソフト記事がより美しくなるように、ユーザーが編集時にさまざまなカスタムメッセージタイプを挿入できるようにする必要があります。そのため、この記事を書いています。 序文 Quill エディターに付属するリッチ テキスト フィルタリング (ほとんどの主流エディターはリッチ テキストをフィルタリングします) が原因で、開発者はカスタム HTML テンプレートを構成するときに多くの問題に遭遇します。 1. クイルレンダリングロジック分析 Quill で HTML ブロック コンテンツをカスタマイズするには、まず Quill の内部レンダリング プロセスを理解する必要があります。理解すべき重要な概念をいくつか示します。 1. デルタ Delta は Quill 内で定義されたデータ形式で、ドキュメントの内容やドキュメントの変更操作を表すために使用されます。読みやすく、シンプルな形式です。ドキュメントの内容は Delta 形式で保持されます。HTML の内容と Delta は相互に変換できます。 例えば: このようなリッチテキストは次の形式で表されます。 { 「オプス」:[ {"挿入":"これは単純なテキストです。\\nただし、"}, {"attributes":{"bold":true},"insert":"それは "}, {"挿入":"太字ではありません。\\n試してみます"}, {"attributes":{"italic":true},"insert":"italic "}, {"挿入":"ははは\\n"}、{"属性": {"italic":true,"bold":true},"insert":"両方"}, {"挿入":" ?\\n"} ] }" 通常のテキストは挿入アクションとして定義され、各項目はテキスト コンテンツの説明であるデルタを表します。 同様に、変更または削除が発生した場合、対応するデルタが生成され、新しく生成された変更デルタが元のデルタとマージされて新しいデルタが生成されます。 (デルタには、挿入、削除、保持の 3 つの操作が含まれます) 最初の 10 文字を保持し、次の 20 文字を太字にします。差分は次のとおりです。 { 「オプス」: [ { "保持": }、 { "保持": 、 "属性": { "太字": } } ] } 最初の 10 文字を保持し、次の 20 文字を削除します。 { 「オプス」: [ { "保持": }、 { "消去": } ] } 2. 羊皮紙 Parchment は、Blots を管理する抽象的なドキュメント モデルです。 Parchment が完全な DOM ツリー構造として理解される場合、Blot はその中の単一のノードです。 Quill のデフォルトの機能に加えて、Blot ではカスタマイズも可能で、拡張の余地が広がります。 3. ブロット Blot は Parchment ドキュメントのコンポーネントであり、DOM ノード タイプの抽象化に相当します。ただし、特定の Blot インスタンスには他のノード情報も含まれています。 グローバル ルート ノード Blot は、Quill によってカスタマイズされたスクロール タイプの Blot であり、その下のすべての Blot を管理します。 Blot の実装定義については、こちらを参照してください: https://github.com/quilljs/parchment#blots Quill における Blot のデフォルトの定義は次のとおりです。 一般的なものには、TextBlot (1 行内の通常のテキスト)、Inline (1 行内のスタイル付き通常のテキスト)、Block (ブロック レベルの行、通常は段落 p 内)、Break (改行)、Image (画像 IMG 挿入)、Bold (太字テキスト) などがあります。 HTML の一部はどのようにしてブロットを構築するのでしょうか? Quill は、ノード タイプに基づいてテキスト ノードを除外する優先順位を決定します。要素ノードの場合は、ノードの ClassName に基づいて再度判断されます。一致する BlotName が見つからない場合は、デフォルトで次のマッピング関係が一致し、対応する BlotClass が検索されます。 4. デルタの実際的意義 コンテンツ構造を表す Blot はすでにあるのに、なぜ Delta が必要なのでしょうか? Delta 自体はコンテンツ データのメンテナンスにすぎません。つまり、ユーザー入力であれ API 操作であれ、HTML の更新はすべて Delta に同期して更新されます。Delta が HTML のデータ ソースとして使用されていない場合、Delta データのコピーを維持する意味は何でしょうか。 HTML => Delta であるが、Delta=> HTML が存在しない場合は、デルタを常に維持する意味は何でしょうか? 1. Delta から HTML を生成することは実際に存在しますが、その適用シナリオはドキュメントの初期化に限定されています。Quill は、受信した初期化 HTML 文字列を解析し、対応する Delta を生成します。次に、Delta を適用して DOM ノードを生成し、ページに表示します。 2. これでもまだ満足できないかもしれません。なぜこのプロセスを実行する必要があるのでしょうか。初期化中に文字列 document.getElementById('container').innerHTML = val を使用すればよいのではないでしょうか。はい、できますが、Delta の存在により、ユーザーのドキュメントはより細分化され、保守しやすく、追跡しやすくなります。 A と B が同時にドキュメントを編集していて、A が 2 行目の 10 文字を削除した場合、ドキュメントのコンテンツ全体を更新する必要はありません。代わりに、A は自分の動作を同期するアクションを送信するだけで済み、B は競合を解決してマージするだけで済みます。 Delta メンテナンスによりロジックはより複雑になりますが、Delta が存在することでドキュメント拡張の可能性も広がります。 5. エディターのレンダリングと更新プロセス コンテンツを変更するには、次の 3 つの方法があります。 1. エディターのコンテンツを初期化します。quill.pasteHTML への呼び出しを初期化し、HTML のフィルタリングと解析を行った後、編集ボックスにエコーします。 2. 入力イベント: ユーザーの入力と編集操作は MutationObserver によって監視および処理され、デルタが更新されます。 3. API 呼び出し: 内部的に提供されている API を、modify メソッドを通じて呼び出し、次にグローバル Scroll インスタンスのメソッドを呼び出して変更します。 2. カスタムHTMLブロックを挿入する 記事の内容が多様化するにつれ、記事内に地図や音楽プレーヤー、広告パネルなどを挿入する必要が生じ、リッチテキストエディタをより多くの機能に拡張する必要が生じています。しかし同時に、XSS 保護攻撃も適切に行う必要があります。 最初の部分によると、カスタム HTML ブロックを挿入する必要があり、Quill がそれを認識できる必要があります。お気づきかと思いますが、Blot をカスタマイズする必要があります。 Blot メソッドを定義することで、Quill は初期化中に HTML ブロックの表示を認識できるようになり、また、HTML ブロックを挿入するときに Quill がダーティ HTML をフィルタリングするのを防ぐこともできます。 登録ブロット方式は以下のとおりです。 デフォルト関数をエクスポートする(Quill){ // ソースコードからBlockEmbedをインポートする const BlockEmbed = Quill.import('blots/block/embed'); // 新しいブロットタイプクラスを定義する AppPanelEmbed extends BlockEmbed { 静的作成(値) { 定数ノード = super.create(値); ノードの属性を設定します('contenteditable', 'false'); ノード.setAttribute('幅', '100%'); // カスタム HTML を設定する node.innerHTML = this.transformValue(値) ノードを返します。 } 静的変換値(値) { handleArr = value.split('\n') とします。 handleArr = handleArr.map(e => e.replace(/^[\s]+/, '') .replace(/[\s]+$/, '')) handleArr.join('') を返します } // 操作を元に戻すためのノード自体の値を返す static value(node) { node.innerHTML を返す } } // ブロット名 AppPanelEmbed.blotName = 'AppPanelEmbed'; // クラス名はブロット名と一致するために使用されます AppPanelEmbed.className = 'embed-innerApp'; // タグ タイプをカスタマイズします AppPanelEmbed.tagName = 'div'; Quill.register(AppPanelEmbed, true); } 次に、カスタム HTML ブロックをエディターに挿入するには、次のように呼び出す必要があります。 quill.insertEmbed(quill.getSelection().index || 0, 'AppPanelEmbed', ` <div class="app_card_header"> カスタムパネルタイトル</div> <div class="app_card_content"> パネルのコンテンツをカスタマイズする</div> <div class="app_card_footer"> フッター </div> `); パラメータ形式の要件は次のとおりです。 insertEmbed(インデックス: Number, タイプ: String, 値: any, ソース: String \= 'api'): Delta これは単なる簡単な例です。カスタム Blot の機能を充実させたい場合は、https://github.com/quilljs/parchment#blots を参照してください。 contenteditable 属性が解放されているため、XSS 攻撃を防ぐために、この属性に対して特別なフィルタリングを実行する必要があります。ここでは、XSS モジュール処理を例に挙げます。 ハンドルWithXss(コンテンツ) { 定数オプション = { ホワイトリスト: { ... div: ['class', 'style', 'data-id', 'contenteditable'], ... }, css: { ホワイトリスト: { 色: 真、 '背景色': true、 '最大幅': true、 }, }, タグを無視: true, onTagAttr: (タグ、名前、値、isWhiteAttr) => { // div の contenteditable を処理します if (isWhiteAttr && tag === 'div' && name === 'contenteditable') { 'contenteditable="false"' を返します。 } }, } // カスタムルール const myxss = new xss.FilterXSS(options) myxss.process(コンテンツ) を返す } Quill エディターでカスタム HTML レコードを挿入する方法に関するこの記事はこれで終わりです。Quill エディターのカスタム HTML コンテンツの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。 |
<<: クロスオリジン画像リソース権限(CORS 対応画像)
>>: ブルートフォース攻撃を防ぐためのシェルスクリプト設定
目次1. 脱構築とは何か? 2. 配列の分割3. 配列モードと代入モードの統一4. デフォルト値の構...
目次過去1週間の時間を取得する過去1か月の時間を取得する過去3か月分を取得新しい Date() と ...
商品を検索するときに、すべてのブランドまたは一部のブランドを表示するTaobaoの機能を真似してみま...
これでtransformコースは終了です。例を見てみましょう。transform transform...
ローカル環境はWindows10+WSL2(Ubuntu)です。サーバーにDockerをインストール...
企業の Web サイト、個人のブログ、ショッピング Web サイト、ゲーム Web サイトなど、どの...
目次概要Big O 表記法とは何ですか?オー(1)の上) (n^2) O(logn) ですの上!)結...
MySQL タイム ブラインド インジェクションの 5 つの遅延方法 (PWNHUB の予期しない解...
ウェブサイトをデザインするにはインスピレーションが必要です。良いインスピレーションを得るには、より多...
Fabric.js は非常に便利なキャンバス操作プラグインです。ここでは、日常のプロジェクトで使用さ...
目次1. TypeScriptが古いVueプロジェクトに導入されるVue+Typescript プロ...
1.docker search mysql查看mysql版本 2. docker pull mysq...
CSS における位置指定の概要position属性は英語で位置を意味し、 CSSでの主な機能は要素...
序文トランザクション データ ディクショナリとアトミック DDL は、MySQL 8.0 で導入され...
序文昨日、h5 WeChat認証の実装が必要なプロジェクトがありました。したがって、この機能を完了す...