web-dev-qa-db-ja.com

contentEditable DIVでの改行の処理

SAFARI/CHROMEでcontenteditableの改行に問題があります。 contentEditable _<div>_で「return」を押すと、_<br>_(Firefoxなど)を作成する代わりに、新しい_<div>_を作成します。

_<div>Something</div>
<div>Something</div>
_

それは次のようになります(contentEditable DIV上):

_Something
Something
_

しかし、サニタイズ(_<div>_を削除)後、私はこれを取得します:

_SomethingSomething
_

Firefoxでは、contenteditableは次のとおりです。

_Something
<br>
Something
_

そして、サニタイズ後も同じように見えます:

_Something
Something
_

これをブラウザ間で「正規化」するソリューションはありますか?

このコードは で見つけましたcontenteditableでEnterを押して<div> </ div>の代わりに<br>を作成します

_$(function(){

  $("#editable")

  // make sure br is always the lastChild of contenteditable
  .live("keyup mouseup", function(){
    if (!this.lastChild || this.lastChild.nodeName.toLowerCase() != "br") {
      this.appendChild(document.createChild("br"));
     }
  })

  // use br instead of div div
  .live("keypress", function(e){
    if (e.which == 13) {
      if (window.getSelection) {
        var selection = window.getSelection(),
          range = selection.getRangeAt(0),
          br = document.createElement("br");
        range.deleteContents();
        range.insertNode(br);
        range.setStartAfter(br);
        range.setEndAfter(br);
        range.collapse(false);
        selection.removeAllRanges();
        selection.addRange(range);
        return false;
      }
    }
  });
});
_

これは機能しますが、(SAFARIとCHROME)「return」キーを2回押して新しい行を取得する必要があります...

何か案が?

編集:私が見つけたコード(この質問の最後にあります)は、「_<br>_要素が常にlastChildであることを確認する機能を除いて、正常に機能しています...これを修正するには?

編集2:コンソールに次のエラーが表示されます:_Uncaught TypeError: Object #<HTMLDocument> has no method 'createChild'_

編集3: OK、document.createChild("br");document.createElement("br");に変更し、FF/Safari/Chromeで動作するようになったと思います...すべてが_<br>_新しい行...

問題は、順序付きリストまたは順序付けられていないリスト内にいるとき、_<br>_...なしで新しい行を取得する必要があることです。

編集4:最後の編集のソリューションに興味がある場合: <LI>要素(contentEditable)内にある場合はcreateElement関数を避けます

54
Santiago

この手法は、BRを最初に表示するChromeバグを回避するようです(言及したコードではEnterキーを2回押す必要があります)。

完全なハックではありませんが、動作します。BRの後に空白が追加されるため、適切に表示されます。ただし、空白「」のみを追加しても何も変更されず、他の文字で機能することがわかります。ブラウザはそれを表示しません。おそらく、htmlページ内の空白スペースのようなもので、単に何も意味しないからです。そのバグを取り除くために、_&nbsp;_タグを含むjQueryを使用してdivを作成し、text()プロパティを取得してtextnodeに配置します。そうしないと機能しません。

_$editables = $('[contenteditable=true]');

$editables.filter("p,span").on('keypress',function(e){
 if(e.keyCode==13){ //enter && shift

  e.preventDefault(); //Prevent default browser behavior
  if (window.getSelection) {
      var selection = window.getSelection(),
          range = selection.getRangeAt(0),
          br = document.createElement("br"),
          textNode = document.createTextNode("\u00a0"); //Passing " " directly will not end up being shown correctly
      range.deleteContents();//required or not?
      range.insertNode(br);
      range.collapse(false);
      range.insertNode(textNode);
      range.selectNodeContents(textNode);

      selection.removeAllRanges();
      selection.addRange(range);
      return false;
  }

   }
});
_
28
Micaël Félix

キーストロークを聞くのは大変な作業のようです。これと同じくらい簡単なことが実現可能でしょうか:

var html = $('.content').html().replace(/<div>/gi,'<br>').replace(/<\/div>/gi,'');

JSFiddleデモ ここ

また、 sanitize.js のように見えるため、カスタム構成が可能です。 divを許可要素として追加しようとしましたか?

HTML/CSSを許可することは危険ですので、十分に注意してください。

EDIT:サーバー側のコメントを削除しました。サニタイズは使用時に行われます。クライアントがこれをローカルでバイパスしたい場合は、独自のリスクで行うことができます。 Vincent McNabb これを指摘してくれてありがとう。

13
Kurt

次のコマンドを使用できますdocument.execCommand('insertHTML',false,'<br>');

このコマンドはデフォルトの動作を防ぎ、希望するタグを追加します。それがすべて、1行のコードです

そしてさらに簡単なアプローチ。

CSSのみ。

Contenteditable要素にdisplay:inline-blockルールを適用すると、br sのみが追加されます

9
Karb

Webkitは、コンテナの最後の(空でない)子である場合、単一のbrをレンダリングしません。 Safariの場合、改行を挿入するためのネイティブキーストロークはCtrl + Returnです。よく見ると、Safariは実際に2つのbrsを挿入し、1つだけをレンダリングしていることに気付きます。ただし、末尾にテキストがある場合は単一のbrを挿入します。また、入力すると、二重のbrsが削除されます(二重がある場合)。

どうやら、Webkitの解決策は、二重のbrsを挿入し、残りを処理させることです。

2
Klim Lee

Css white-spaceプロパティをチェックアウトすることをお勧めします。スタイルをwhite-space: pre-wrapに設定すると、そのJavaScriptをすべて削除できます。これは、折りたたみではなく表示する空白の動作を変更するためです。

この回答を参照してください: HTML-DIVコンテンツの改行文字は編集可能?

1
B T

次を使用できます。

document.execCommand("defaultParagraphSeparator", false, "br");

完全なリファレンスは here です

0
Saeed
0
user10