web-dev-qa-db-ja.com

HTMLコンテンツは編集不可のアイランドで編集可能

私は、ユーザーがドキュメントテンプレートを編集できるブラウザベースのWYSIWYGエディタを持っています。

ドキュメントテンプレートは、いくつかの特別な「マージコードプレースホルダー」を持つ通常のhtmlです。このようなテンプレートは、これらのプレースホルダーをDBからのデータで置き換えることによって「インスタンス化」されます。これにより、最終的なドキュメント、つまりテンプレートのインスタンスが提供されます。

私の現在のアプローチは次のようになります:

<div contenteditable>
  Sample template with <input type=button class="mergecode" value="MergeCode1">.
</div>

(使用するオンラインサンプル: http://jsfiddle.net/tFBKN/

そのような場合、入力は編集できず、固体ブロックとして動作します-まさに私が必要なものです。ユーザーは、DELまたはBACKSPACEをクリックして、他の文字などのそのようなマージコードを削除できます。そのようなinput.mergecodeに適切なCSSを設定することで、必要なルックアンドフィールを実現できます。

しかし、そのようなアプローチでは、3つの異なるUAで3つの異なる問題があります。

  • IE-CSS { font:inherit }はそこで機能しません。したがって、入力が<b>の内部にある場合、<b><input value="test"></b>はフォントスタイルを継承しません。
  • FF-<input>要素を含むフラグメントのコピーは、その入力をクリップボードのコンテンツから削除するため、さらに貼り付け操作を行うと、入力以外のすべてが挿入されます。
  • GC-<input>が奇妙な結果を生成した直後に{BACKSPACE}をクリックします( bug

したがって、HTMLで編集不可能なインラインブロックのような「島」を表現する方法に関する他のアイデアを探しています。

これまでに試した他のアプローチ:

  • <span contenteditable="false">MergeCode1</span>-ほとんどのUAがそのようなノードを選択から削除するため、機能しません。したがって、たとえば、そのようなスパンを含む選択範囲の上に<b>または<i>を適用することはできません。

他のアイデアはありますか?

32
c-smile

有望に見えるもう1つのアイデア:

::before { content:"caption"; }で空のスパンを使用すると、内部にキャレット位置のないノードとしてDOMで表される編集不可能なブロックが生成されます。

ここで試すことができます http://jsfiddle.net/TwVzt/1/

しかし、このアプローチには問題がないわけではありません(私の場合):styleDOM属性を使用してインラインで::beforeを宣言する方法はありません。セット全体を事前にCSSで宣言する必要があります。しかし、私が持っているマージコードのセットは非常に大きく、一部のユースケースでは完全に不明なものもあります。はぁ。

それでも、誰かがより良い状況(既知のコードセット)を持っている場合は、このレシピをここに配置します。

11
c-smile

私はCKEditor開発者です。ネストされた読み取り専用要素(つまり placeholder プラグインと現在取り組んでいる機能 #9764 )での経験があり、私はしません良いニュースがあります。一貫したルックアンドフィールを実現するには、すべての動作を手動で処理する必要があります。ブラウザを修正するトリックはありません。そして、多くのことが(GCの入力の周りで起こっている奇妙なことがこのように)解決できないようです。

22
Reinmar

私は同様の問題に遭遇した古いスレッドを知っています。編集可能なdivに編集不可能なスパンがいくつか必要でした。のようなハックアラウンドを実装してしまった...

$('#testDiv').on('keydown', function(e) { 
    var targetNode = getSelectionStart();
    if(targetNode != undefined && targetNode.nodeType === 1 && targetNode.nodeName == 'SPAN')    
    {
      var nodeHtmlString = targetNode.outerHTML;

      if(~nodeHtmlString.indexOf("nonEditable"))
      {
        e.preventDefault();
        e.stopPropagation();
      }
    }
});

function getSelectionStart() {
 var node = document.getSelection().anchorNode;
 return (node.nodeType == 3 ? node.parentNode : node);
}

https://jsfiddle.net/fxmb3nL6/20/ でフィドルを完成させます

3
Pravin

以下の解決策-小さな注意点があります。しかし、最初に-あなたたちは素晴らしいです!
私はJSやHTMLの専門家ではありませんが、jsfiddle.netについても知りませんでした。コメントとその他のオンライン検索、およびjsfiddleでのテストを読んで、機能する次のコードを作成しました。

<pre><code>
<div contenteditable="false" class="editor" readonly="true" UNSELECTABLE="ON">
    Sample template with <span class="mergecode test1" />.
    <span contenteditable> editable </span>
    <font color=red><span UNSELECTABLE="ON" contenteditable="false" readonly="true"
     UNSELECTABLE="ON">  uneditable1 </span></font>
    <span contenteditable> editable2 </span>
    <font color=red><span contenteditable=false readonly="true" UNSELECTABLE="ON"> uneditable3</span></font>  
    <span contenteditable> editable4 </span>
    <span contenteditable="false" readonly="true" UNSELECTABLE="ON"> uneditable5 </span>
< /div>
</code></pre>

これをjsfiddleにchromeで挿入すると、chrome(and IE and FFでも少し別に)、しかし、小さな警告があるようです。

警告は、キーバインディングがBackspaceで行うことです。私の場合、編集できないフレーズを選択してChromeでバックスペースを押すと、それが更新されるか、「最後のページに移動」するようです。最初の2つの編集不可を赤(最後の黒は左)にして、何が起こるかを確認できるようにしました。私はjsfiddleでChromeとFFとIEでテストします。すべてが正常に動作しているようで、バックスペースの問題が発生するか、発生します。

そして、私はそれがどのように機能するかの論理だと思います。最初のDivは最上位の親であり、contenteditable = "false"です。したがって、その下にあるすべてのものは編集できません。スパンcontenteditble = "true"を持つ子を除いて、編集可能になります。したがって、親から継承しますが、その後、子として上書きできます。

また、タグreadonly = "true" UNSELECTABLE = "ON"も配置しました。そしてそれはより多くのテストを要しました!!!注意フォントをスパンの外に持っていかなければなりません...そうしないと機能しません。しかし、IEで完全に機能しました。編集不可は、私が言った色で、シングルクリック、ダブルクリック、トリプルクリックのどれもjsfiddleで編集不可を選択しませんでした!!! :-) Chromeシングルクリックで何もせず、ダブルクリックで編集不可を選択しました。バックスペースを使用すると、少しおかしくなりました!前のページに移動するように見えました。その前に編集不可と編集可能を選択しました!理由がわかりません。

誰かがChromeおよびFFの問題を理解して書くことができればそれは素晴らしいことです。ダブルクリックまたは任意の数の高速クリックが機能しないのはいいことですChromeとFFも。スパンを強調したいのですが...編集不可とフォントの隣にあるようです...スパンの外側にあります。

これがすべて理にかなっていることを願っています。

2
user96265