Slate または ProseMirror を使用してエディターを作成しているときに、Chromeを使用してキャレットの位置と選択領域を囲むと、奇妙な動作が発生する場合があります。インライン要素を使用しています。問題1は下の最初の図に示されています。テキストカーソルの位置が「f」の後ろにある場合、キャレットは画像の上部に表示されます。問題2は2番目の画像にあります-テキストを選択すると表示されますインライン化された要素と同じ高さの強調表示された領域。この動作を制御して、代わりにテキストの位置にキャレットを表示し、テキストの周囲のスペースのみを強調表示する方法はあります(インライン画像が行を作成している場合でも)高さが大きい)
ここでProseMirrorデモを使用してサンプル画像を作成しました: https://prosemirror.net/examples/basic/
JSBin を使用した最小の例(@Kaiidoに感謝):
<div contenteditable>Test text<img src="https://upload.wikimedia.org/wikipedia/en/9/9b/Yoda_Empire_Strikes_Back.png">Testing</div>
他のオペレーティングシステムでこれがどのように動作するかはわかりませんが、私はmacOS Catalinaを使用しています。
まず、JQueryの例に示すように、ProseMirror DOMを操作しないでください。実際、DOMまたはコンテンツの問題に遭遇する可能性が最も高くなります。 ProseMirrorは独自のDOMノードとマークアップスキーマを使用します。 ProseMirror DOMを操作したり、プラグインを追加したりする場合は、マークアップ、プラグイン、およびNode Apisをご覧ください。マークアップコードをテキストで配置する簡単な例を添付しました。補足事項、文法の理由他の人がProseMirrorプラグインを持っていないのは、DOMのアプローチ/モデルが原因です。ProseMirrorは非常に優れていますが、正直に言うと、高度な開発者向けソリューションです。
それはさておき、CSSだけの問題は朗報です。 ProseMirrorはすべてのクラスを取り除き、DOM/CSSをリセットするため、ドキュメントをインポートしたり、すべてをカットアンドペーストしたりすると、ほとんどのクラスが失われます。
これを解決する最も簡単な方法は、エディターをdivでラップし、クラスをdivに割り当てて、そのクラスにスタイルと子スタイルを追加することです。ラップする理由は、img、p、hなどのCSSセレクターがエディタークラス内のタグにのみ適用されるためです。それがなければ、明らかなCSSの衝突が発生します。
[〜#〜] css [〜#〜]
float: left;
(推奨されるアプローチ)vertical-align: baseline;
で修正できますが、フロートなしでは、テキストではなく画像の高さに一致するカーソルが残っているためです。 。また、フロートを使用しない場合、行の高さが画像と実質的に同じであるため、カーソルは長くなります。青色はセレクターにすぎず、CSSを使用しても変更できます。<html>
<div class="editor">
<!-- <editor></editor>-->
</div>
</html>
<style>
.editor {
position: relative;
display: block;
padding: 10px;
}
.editor p {
font-weight: 400;
font-size: 1rem;
font-family: Roboto, Arial, serif;
color: #777777;
display: inline;
vertical-align: baseline;
}
.editor img {
width: 50px;
float: left;
padding: 20px;
}
</style>
ノード拡張の例
Nodeの例です。ツールバーとして追加できるテキスト配置の拡張機能です。投稿はかなり長くなりますが、Node /画像のプラグインを作成した場合でもレンダリングの方法、つまりbase64とurlなどを処理する必要があります。これはなぜそうしたのかについては完全に理にかなっていますが、SEOなどを求める開発者に複雑さを追加するだけです。
export default class Paragraph extends Node {
get name() {
return 'paragraph';
}
get defaultOptions() {
return {
textAlign: ['left', 'center', 'right'],
}
}
inputRules({ type }) {
return [
markInputRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)$/, type),
]
}
get schema() {
return {
attrs: {
textAlign: {
default: 'left'
}
},
content: 'inline*',
group: 'block',
draggable: false,
inclusive: false,
defining : true,
parseDOM: [
{
tag: 'p',
style: 'text-align',
getAttrs: value => value
}
],
toDOM: (node) => [ 'p', {
style: 'text-align:' + node.attrs.textAlign,
class: `type--base type--std text-` + node.attrs.textAlign
}, 0 ]
};
}
commands ({ type }) {
return (attrs) => updateMark(type, attrs)
}
}