web-dev-qa-db-ja.com

ENTERでコンテンツ編集可能<div>を追加できない-Chrome

contenteditable要素があり、何かを入力してENTERを押すと、新しい<div>が作成され、そこに新しい行テキストが配置されます。私はこれが少し好きではありません。

これを防ぐことはできますか、少なくとも<br>に置き換えてください。

デモhttp://jsfiddle.net/jDvau/

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

107
iConnor

これを試して

$('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><br>');
      // prevent the default behaviour of return key pressed
      return false;
    }
  });

ここでデモ

150
Ram G Athreya

CSSを変更するだけでこれを実行できます。

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

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

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

44
airi

スタイルdisplay:inline-block;contenteditableに追加すると、Chromeでdivp、およびspanが自動的に生成されません。

33
Le Tung Anh

これを試して:

$('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/

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

代わりに段落を持つようにデフォルトの動作をオーバーライドします。

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

<div>
    <br>
</div>

そのコマンドでそれはなるだろう

<p>
    <br>
</p>

全体的に線形になったので、必要なのは<br>だけにするのは簡単です。

13
Ced

つかいます shift+enter の代わりに enter 単一の<br>タグを挿入するか、<p>タグでテキストをラップするだけです。

11
Blake Plumb

を押したときのcontenteditableの動作 enter ブラウザに依存し、<div>はWebkit(chrome、safari)および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);
            }
        }
    });
}

それが助けになることを望み、必要に応じて明確でない場合は私の英語を申し訳ありません。

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

6
Elie

この問題を解決するには、スタイリング(Css)を使用します。

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

Firefoxは実際にブロック要素ブレークを追加します
に対して、Chromeはタグ内の各セクションをラップします。 cssは、divに背景色と共に10pxのパディングを与えます。

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/

4
cbayram

divに防ぐデフォルトを追加します

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

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

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

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

<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を作成しますandカーソルは先頭に戻されます次のdivに移動する代わりに現在のdiv。

Chrome、Firefox、およびEdgeでテスト済み。

4
Josh Powlison

Ckeditorを使用してみてください。また、SOFでこのようなフォーマットを提供します。

https://github.com/galetahub/ckeditor

3
Dan Rey Oquindo

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

3
nes

最初にすべてのキーユーザーEnterをキャプチャして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
L105
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');を意味する実際のコンテキストです。

2
webprogrammer

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
skerit

これはブラウザー向けの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
Mehdi

これと同じ問題があり、解決策(CHROME、MSIE、FIREFOX)が見つかりました。リンクのコードに従ってください。

$(document).on('click','#myButton',function() {
    if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1)
        var str = $('#myDiv').html().replace(/<br>/gi,'').replace(/<div>/gi,'<br>').replace(/<\/div>/gi,'');
    else if (navigator.userAgent.toLowerCase().indexOf("firefox") > -1)
        var str = $('#myDiv').html().replace(/<\/br>/gi,'').replace(/<br>/gi,'<br>').replace(/<\/br>/gi,'');
    else if (navigator.userAgent.toLowerCase().indexOf("msie") == -1)
        var str = $('#myDiv').html().replace(/<br>/gi,'').replace(/<p>/gi,'<br>').replace(/<\/p>/gi,'');    
    $('#myDiv2').removeClass('invisible').addClass('visible').text(str);
    $('#myDiv3').removeClass('invisible').addClass('visible').html(str);
});

https://jsfiddle.net/kzkxo70L/1/

1

別の方法

$('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/

1
BlueUnicorn

各Enterキーでコンテンツ編集可能なDivで新しいDivが作成されないようにする:私が見つけた解決策は非常に簡単です:

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

この--- innerHTMLコンテンツは、各Enterキーで編集可能なコンテンツDivでの新規Div作成を防ぎます。

1

ホットキーの処理にMousetrapを使用するのが好きです: 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");
0
Gauss