ENTERでcontenteditableが<div>を追加できないようにする-Chrome


131

私が持っているcontenteditable要素を、と私はいくつかのものを入力するたびにヒットし、ENTERそれが新しいを作成<div>し、そこに新しい行のテキストを配置します。これは少し気に入らない。

これが起こらないようにすることはできますか、少なくともそれを単に<br>

こちらがデモですhttp://jsfiddle.net/jDvau/

注:これは、Firefoxの問題ではありません。


1
firefoxは<br>を追加しますが、クロムは追加しませんが、スタイルを修正した後、余分なdivが左パディングを壊しません。質問はなぜあなたがそれを好きではないのですか?br ... jsfiddle.net/jDvau/1また、これらのdivをキャッチして削除するためにDOMSubtreeModifiedイベントを使用できます。
ViliusL 2013


1
私にとって、Blake Plumbのソリューションは最も単純であり、ここからはるかに優れています。
svassr 2013

1
@svassrはポイントではありません。それを使用するのはあなたでも私でもありません。シフトが何であるかさえ知らないかもしれないクライアントです。
iConnor 2013

2
実際、それはすべてを変えます。それはそれが一般的な振る舞いであり、小さなヘルプメッセージは武装しないと述べました。「人に魚を与え、あなたは彼に1日間餌を与えます。人に釣りを教えると、あなたは彼に一生与えます。」
svassr 2013

回答:


161

これを試して:

$('div[contenteditable]').keydown(function(e) {
    // trap the return key being pressed
    if (e.keyCode === 13) {
        // insert 2 br tags (if only one br tag is inserted the cursor won't go to the next line)
        document.execCommand('insertHTML', false, '<br/>');
        // prevent the default behaviour of return key pressed
        return false;
    }
});

デモはこちらをクリックしてください


しかし、ここでは少し違いがあります。空白行(「Type some stuff」の上部)にカーソルを置き、Enterキーを押します。カーソルは、新しい空白行ではなく、「タイプ」の直前にあります。
Andrew

3
insertHTMLをサポートしていないため、これはIE11では機能しません。以下の答えを見てください!
Webプログラマ

4
カーソルを文字の間に置くと、「Ty [cursor] pe some stuff」と入力してEnterキーを押すと、1行が多すぎます。
チャンドリュー2014年

13
回答は受け付けられません。解決策は、<br />を1つだけにすることです
raoulinski

3
これは<br>と<div>の両方を返します
Nishad Up

51

CSSを変更するだけでこれを行うことができます:

div{
    background: skyblue;
    padding:10px;
    display: inline-block;
}

pre{
    white-space: pre-wrap;
    background: #EEE;
}

http://jsfiddle.net/ayiem999/HW43Q/


1
インラインブロックを使用し、execCommand( "insertHTML"、xxx)を実行して何かを挿入すると問題が発生しました。挿入された要素の末尾に「<br>」が追加され、Chrome33でテストされました。
Imskull 2014年

5
いい発見。残念なことに、これは位置では機能しません。絶対要素またはdisplay:flexを持つ親の直接の子である要素。それを念頭に置いて、ハッキングして機能させることができます。それがflex要素の直接の子でないことを確認してください。あなたがそれを必要とする場合:絶対にそれを追加の親に与えてください。
懐疑論者

@ReinoutvanKempen 3か月前にflexの使用を開始しました。このハックは機能しないと思います
kittu 2017

これは本当に最高のソリューションです。非常にクリーンでクリアで、brを含めても何も挿入されません。特にjsなしのこのソリューション。
オルカを守る

2
うわー...これでChromeは解決しますが、FirefoxはEnterでdivを追加し始めますが、デフォルトではそうではありません。
cbdeveloper

40

スタイルを追加display:inline-block;するためにcontenteditable、それは生成されませんdivpspan自動的にクロームインチ


6
これは素晴らしいソリューションです。*[contenteditable="true"]{display: inline-block;}
ericjbasti

愛する、シンプルだが効果的
user25794

IE11では、これにより追加の:<p></p>
Betty St

1
しかし、それは別の非常に迷惑なChromeバグ(なんと
ひどい

4
クロームバージョン63.0.3239.84でもう動作しません
ミカエル・メイヤー

21

これを試して:

$('div[contenteditable="true"]').keypress(function(event) {

    if (event.which != 13)
        return true;

    var docFragment = document.createDocumentFragment();

    //add a new line
    var newEle = document.createTextNode('\n');
    docFragment.appendChild(newEle);

    //add the br, or p, or something else
    newEle = document.createElement('br');
    docFragment.appendChild(newEle);

    //make the br replace selection
    var range = window.getSelection().getRangeAt(0);
    range.deleteContents();
    range.insertNode(docFragment);

    //create a new range
    range = document.createRange();
    range.setStartAfter(newEle);
    range.collapse(true);

    //make the cursor there
    var sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);

    return false;
});

http://jsfiddle.net/rooseve/jDvau/3/


よし、うまくいくよ:)決断する前にもっと注目してもらいたい。ありがとう。
iConnor 2013

Firefoxでは正しく動作しません。1行追加されます。
agpt 2016

これにより、inputEnterキーを押したときにがトリガーされなくなります。簡単な解決策:$(this).trigger('input')
sthを次の

insertHTMLソリューションは、ネストされたがあるときにいくつかの奇妙なことを行いcontenteditable要素、あなたのソリューションを回避することがなく、いくつかのより多くの問題がある、私は新しい可能な解決策として、これを追加しました。
スケリット2018

Chromeでは動作しません。文字列の最後で初めてEnterキーを押すと、スペースが追加されます。2回目は機能します。

20
document.execCommand('defaultParagraphSeparator', false, 'p');

代わりに段落を持つようにデフォルトの動作を上書きします。

chromeでは、Enterのデフォルトの動作は次のとおりです:

<div>
    <br>
</div>

そのコマンドを使用すると、

<p>
    <br>
</p>

全体的に線形になっているので、<br>必要なものだけを簡単に持つことができます。


Enterキーを押すと、divとbrの代わりに、ブラウザー全体でpとbrが表示されます。それを試してみてください。
Ced 2016

ありがとう!説明は常に役に立ちます
jpaugh

@jpaugh np、私は自分の答えをさらに編集して、よりよく説明できるようにしました。
2016

これはFirefoxでは機能しません(私は
Chrome

FireFoxが修正され、defaultParagraphSeparatorが考慮されるようになりました。私見これにより、すべてのブラウザーが仕様に一致し、インライン化されるようになるため、この答えが最良になります。次に、Pタグに、編集可能なコンテンツの前のテキストブロックからの「間隔」のマージンを持たせたくない場合は、cssを使用して変更できます。
blackmamba

9

代わりにshift+ enterを使用してenter、単一の<br>タグを挿入するか、テキストを<p>タグで囲みます。


9
+1おかげで、これは知っておくと非常に便利ですが、本を書いているクライアントがいる場合、***
iConnorは12:12の

1
コンテンツを貼り付けている場合、これは役に立ちません
vsync

5

やり方contenteditableを押す振る舞うが、enterブラウザに依存しては、<div>WebKitの(クロム、サファリ)とIEで発生します。

私はこの数か月前に苦労し、それをこのように修正しました:

//I recommand you trigger this in case of focus on your contenteditable
if( navigator.userAgent.indexOf("msie") > 0 || navigator.userAgent.indexOf("webkit") > 0 ) {
    //Add <br> to the end of the field for chrome and safari to allow further insertion
    if(navigator.userAgent.indexOf("webkit") > 0)
    {
        if ( !this.lastChild || this.lastChild.nodeName.toLowerCase() != "br" ) {
            $(this).html( $(this).html()+'<br />' );
        }
    }

    $(this).keypress( function(e) {
        if( ( e.keyCode || e.witch ) == 13 ) {
            e.preventDefault();

            if( navigator.userAgent.indexOf("msie") > 0 ) {
                insertHtml('<br />');
            }
            else {
              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);
            }
        }
    });
}

私はそれが役に立てば幸いです、そしてそれが必要とされるほど明確でないなら私の英語を申し訳ありません。

編集:削除されたjQuery関数の修正jQuery.browser


ただお知らせするだけですが、jQuery.browserjQueryの一部ではなくなりました。
iConnor

あなたが右ましたが、私はこれと使用のようなものを言及する必要がありますnavigator.userAgent.indexOf("msie") > 0し、navigator.userAgent.indexOf("webkit") > 0
エリー

1
if( ( e.keyCode || e.witch ) == 13 ) { ... }する必要がありますif (e.keyCode === 13 || e.which === 13) { ... }
Sebastian Sandqvist

5

ホットキーのハンドリングにマウストラップを使用したい:https ://craig.is/killing/mice

次に、Enterイベントをインターセプトして、コマンドinsertLineBreakを実行します

Mousetrap.bindGlobal('enter', (e)=>{
  window.document.execCommand('insertLineBreak', false, null);
  e.preventDefault();
});

すべてのコマンド:https : //developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

Chrome 75と次の編集可能な要素を使用して動作します。

<pre contenteditable="true"></pre>

insertHTMLを使用することもできます。

window.document.execCommand('insertHTML', false, "\n");

4

divにデフォルトの防止を追加する

document.body.div.onkeydown = function(e) {
    if ( e.keycode == 13 ){
        e.preventDefault();
            //add a <br>
        div = document.getElementById("myDiv");
        div.innerHTML += "<br>";
    }
}

@connorspiracistは申し訳ありませんdocument.body.divdiv一般的なアイデアを修正するには、他のコードを挿入する必要があります)
Math chiller

4

スタイリング(Css)を使用して問題を修正します。

div[contenteditable=true] > div {
  padding: 0;
} 

実際、Firefoxはblock要素のbreakを追加しますが、
Chromeは各セクションをタグで囲みます。あなたはCSSは背景色と一緒にdiv10pxのパディングを与えます。

div{
  background: skyblue;
  padding:10px;
}

あるいは、jQueryで同じ望ましい効果を複製できます。

var style = $('<style>p[contenteditable=true] > div { padding: 0;}</style>');
$('html > head').append(style);

ここにあなたのフィドルのフォークがありますhttp://jsfiddle.net/R4Jdz/7/


1
これは、いくつかの人々を助けるかもしれないが、私は最終的なHTML服用されるように、私は、もっとunessasaryマークアップを懸念したcontenteditableと他の場所でそれを使用して
iConnor

4

<p>タグを使用するのではなく、各行に個別のタグを設定<br>して、すぐにブラウザーの互換性を高めることができます。

これを行うに<p>は、contenteditable div内にデフォルトのテキストを含むタグを配置します。

たとえば、次の代わりに:

<div contenteditable></div>

使用する:

<div contenteditable>
   <p>Replace this text with something awesome!</p>
</div>

jsfiddle

Chrome、Firefox、およびEdgeでテストされ、2番目はそれぞれ同じように動作します。

ただし、1つ目は、Chromeでdivを作成し、Firefoxで改行を作成し、Edgeでdivを作成、カーソルを次のdivに移動するのではなく、現在のdivの先頭に戻します。

Chrome、Firefox、Edgeでテスト済み。


これは実際には悪い解決策ではありません
AaronHS

3

段落を<p>タグでラップできます。たとえば、divの代わりに新しい行に表示され
<div contenteditable="true"><p>Line</p></div>
ます。例:新しい文字列を挿入した後:
<div contenteditable="true"><p>Line</p><p>New Line</p></div>


3

inserHTMLコマンド・ソリューションを使用すると、ネストされた持っているいくつかの奇妙な行いcontenteditableの要素を。

私はここで複数の回答からいくつかのアイデアを取り入れましたが、これは今のところ私のニーズに合っているようです:

element.addEventListener('keydown', function onKeyDown(e) {

    // Only listen for plain returns, without any modifier keys
    if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) {
        return;
    }

    let doc_fragment = document.createDocumentFragment();

    // Create a new break element
    let new_ele = document.createElement('br');
    doc_fragment.appendChild(new_ele);

    // Get the current selection, and make sure the content is removed (if any)
    let range = window.getSelection().getRangeAt(0);
    range.deleteContents();

    // See if the selection container has any next siblings
    // If not: add another break, otherwise the cursor won't move
    if (!hasNextSibling(range.endContainer)) {
        let extra_break = document.createElement('br');
        doc_fragment.appendChild(extra_break);
    }

    range.insertNode(doc_fragment);

    //create a new range
    range = document.createRange();
    range.setStartAfter(new_ele);
    range.collapse(true);

    //make the cursor there
    let sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);

    e.stopPropagation();
    e.preventDefault();

    return false;
});

// See if the given node has a next sibling.
// Either any element or a non-empty node
function hasNextSibling(node) {

    if (node.nextElementSibling) {
        return true;
    }

    while (node.nextSibling) {
        node = node.nextSibling;

        if (node.length > 0) {
            return true;
        }
    }

    return false;
}


2

最初に、ユーザーが入力するすべてのキーをキャプチャして、Enterキーが押されているかどうかを確認する必要があります。次に、<div>作成を防ぎ、独自の<br>タグを作成します。

1つの問題があります。それを作成すると、カーソルは同じ位置に留まるため、Selection APIを使用してカーソルを最後に配置します。

<br>テキストの最後にタグを追加することを忘れないでください。そうしないと、最初の入力で新しい行が作成されません。

$('div[contenteditable]').on('keydown', function(e) {
    var key = e.keyCode,
        el  = $(this)[0];
    // If Enter    
    if (key === 13) {
        e.preventDefault(); // Prevent the <div /> creation.
        $(this).append('<br>'); // Add the <br at the end

        // Place selection at the end 
        // http://stackoverflow.com/questions/4233265/contenteditable-set-caret-at-the-end-of-the-text-cross-browser
        if (typeof window.getSelection != "undefined"
            && typeof document.createRange != "undefined") {
            var range = document.createRange();
            range.selectNodeContents(el);
            range.collapse(false);
            var sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (typeof document.body.createTextRange != "undefined") {
            var textRange = document.body.createTextRange();
            textRange.moveToElementText(el);
            textRange.collapse(false);
            textRange.select();
        }
    }
});

フィドル


2

これはブラウザ向けのHTML5エディタです。テキストを<p>...</p>でラップすると、Enterキーを押すたびに表示されます<p></p>。また、エディターは、Shift + Enterキーを押すたびに挿入されるように機能します<br />

<div contenteditable="true"><p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolor veniam asperiores laudantium repudiandae doloremque sed perferendis obcaecati delectus autem perspiciatis aut excepturi et nesciunt error ad incidunt impedit quia dolores rerum animi provident dolore corporis libero sunt enim. Ad magnam omnis quidem qui voluptas ut minima similique obcaecati doloremque atque!
<br /><br />
Type some stuff, hit ENTER a few times, then press the button.
</p>
</div>

これを確認してください:http : //jsfiddle.net/ZQztJ/


2

これはすべての主要ブラウザ(Chrome、Firefox、Safari、Edge)で機能します

document.addEventListener('keydown', event => {
  if (event.key === 'Enter') {
    document.execCommand('insertLineBreak')
    event.preventDefault()
  }
})
<div class="element" contenteditable="true">Sample text</div>
<p class="element" contenteditable="true">Sample text</p>

不便な点が1つあります。編集が終了すると、要素の<br>内部に末尾が含まれる場合があります。ただし、必要に応じて、コードを追加して削減することができます。

この回答をチェックして、末尾のhttps://stackoverflow.com/a/61237737/670839を削除して<br> ください


一体何ですか?実際に私にとって実際に機能した唯一の解決策は、このページの一番下にあるのでしょうか?本当にありがとう。
user12861

1
if (navigator.userAgent.toLowerCase().indexOf('msie') > -1) {
   var range = document.getSelection();
   range.pasteHTML(range.htmlText + '<br><br>');
}
else if(navigator.userAgent.toLocaleLowerCase().indexOf('trident') > -1)                           {
   var range = document.getSelection().getRangeAt(0); //get caret
   var nnode = document.createElement('br');
   var bnode = document.createTextNode('\u00A0'); //&nbsp;
   range.insertNode(nnode);
   this.appendChild(bnode);
   range.insertNode(nnode);                                
}
else
   document.execCommand('insertHTML', false, '<br><br>')

どこにthisどの手段の実際のコンテキストがありますdocument.getElementById('test');


0

それを行う別の方法

$('button').click(function(){
    $('pre').text($('div')[0].outerHTML)
});

$("#content-edit").keydown(function(e) {
    if(e.which == 13) {
       $(this).find("div").prepend('<br />').contents().unwrap();
      }
});

http://jsfiddle.net/jDvau/11/


入力時にカーソルが前方に移動することはありません。
Jack Lu

これは奇妙なことです。ChromeとIE 11で試したところ、問題なく動作しました。 参考 使用しているブラウザを教えてください。動作についてこれ以上の詳細があれば、問題の解決に役立ちます
MrAJ

0

Enterキーごとにコンテンツ編集可能なDivで新しいDivを作成しない:解決策私が見つけたのは非常に簡単です:

var newdiv = document.createElement("div"); 
newdiv.innerHTML = "Your content of div goes here";
myEditablediv.appendChild(newdiv);

この--- innerHTMLコンテンツにより、Enterキーごとにコンテンツ編集可能なDivでNew Divが作成されなくなります。


0

W3Cエディターのドラフトには、ContentEditableへの状態の追加に関する情報がいくつかあります。Enterキーを押したときにブラウザーが新しい要素を追加しないようにするには、を使用できますplaintext-only

<div contentEditable="plaintext-only"></div>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.