ENTER에서 <div>를 추가 할 수있는 콘텐츠 편집 금지-Chrome


131

나는 contenteditable요소를 가지고 있으며 , 물건을 입력하고 칠 때마다 ENTER새로운 것을 만들고 <div>새로운 줄 텍스트를 거기에 넣 습니다. 나는 이것을 조금 좋아하지 않습니다.

이 문제가 발생하는 것을 막을 수 <br>있습니까? 아니면 적어도 ?

데모는 http://jsfiddle.net/jDvau/입니다.

참고 : 이것은 firefox의 문제가 아닙니다.


1
firefox는 크롬을 추가하지 않지만 스타일을 수정 한 후에 여분의 div가 왼쪽 패딩을 중단하지 않습니다. 질문은 왜 당신이 그것을 싫어합니까? br ... jsfiddle.net/jDvau/1 이라고 생각하십시오 .이 div를 잡아서 제거 할 때 DOMSubtreeModified 이벤트를 사용할 수도 있습니다.
ViliusL

stackoverflow.com/questions/6024594/… 도움이 될 수 있습니다. 행운을 빌어 요!
시리 콘

1
나에게 Blake Plumb의 솔루션은 가장 간단하고 가장 좋은 방법입니다.
svassr

1
요점이 아닌 @ svassr, 당신이나 내가 사용하지 않을 것입니다, 그것은 교대가 무엇인지조차 모르는 클라이언트입니다.
iConnor

2
실제로 모든 것을 바꿉니다. 그것은 일반적인 행동이며 작은 도움말 메시지는 적합하지 않다고 말했습니다. "남자에게 물고기를주고 하루 동안 먹이를 준다. 남자에게 물고기를 가르치면 평생 먹이를 준다."
svassr

답변:


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;
    }
});

데모를 보시려면 여기를 클릭하십시오


그러나 나는 여기에 약간의 차이가 있습니다. 빈 줄 ( "일부 입력"상단)에 커서를 놓고 Enter 키를 누릅니다. 커서는 이제 새 빈 줄이 아니라 "유형"바로 앞에 있습니다.
앤드류

3
IE11에서는 insertHTML을 지원하지 않으므로 작동하지 않습니다. 아래 답변을 참조하십시오!
webprogrammer

4
예를 들어 문자 사이에 커서를 놓으면 '커서로 물건을 깎아 라'를 입력하고 엔터를 치면 1 줄이 너무 많습니다.
Chandrew

13
대답은 용납되지 않습니다. 해결책은 <br /> 하나만있는 것입니다
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

5
좋은 발견. 슬프게도 이것은 위치에서 작동하지 않습니다 : 절대 요소 또는 표시가있는 부모의 직계 자녀 인 요소 : flex. 그것을 염두에두고 작동하도록 해킹 할 수 있습니다. 플렉스 요소의 직접적인 자식이 아닌지 확인하십시오. 당신이 그것을 필요로하는 경우 : 절대 그에게 여분의 부모를 줘.
회의론자

@ReinoutvanKempen 이미 3 개월 전에 flex를 사용하기 시작했습니다. 이 핵이 작동하지 않는 것 같아요
kittu

이것은 정말 최고의 솔루션이며, 매우 깨끗하고 명확하며 삽입 할 것이 없으며 br도 포함합니다. 특히 js가없는이 솔루션.
orca

2
와우 ...이 Chrome을 해결하지만 Firefox가 enter에 div를 추가하기 시작합니다. 기본적으로 그렇지 않습니다.
cbdeveloper

40

스타일을 추가 display:inline-block;하기 위해 contenteditable, 그것은 생성하지 않습니다 div, p그리고 span자동으로 크롬있다.


6
이것은 훌륭한 솔루션입니다. *[contenteditable="true"]{display: inline-block;}
ericjbasti

간단하지만 효과적

IE11에서 이것은 추가를 만들 것입니다 <p></p> :(
Betty St

1
그러나 그것은 또 다른 매우 성가신 Chrome 버그를 생성합니다 (매우 브라우저)
vsync

4
더 이상 Chrome 버전 63.0.3239.84에서 작동하지 않습니다
Mikaël Mayer

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

파이어 폭스에서 제대로 작동하지 않습니다. 한 줄을 더 추가합니다.
augpt

이것은 inputenter를 누를 때 트리거되지 않도록합니다. 간단한 해결책 : 다음과 같은 sth 추가$(this).trigger('input')
LarsW

insertHTML솔루션은 중첩이 몇 가지 이상한 일 수행 contenteditable, 요소 솔루션의 우회가 있지만 좀 더 문제가, 나는 새로운 해결 방안으로 추가했다.
skerit

Chrome에서는 작동하지 않습니다. 문자열 끝에서 Enter 키를 처음 누르면 공백이 추가됩니다. 두 번째로 작동합니다.

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

대신 단락을 갖도록 기본 동작을 재정의합니다.

크롬에서 입력시 기본 동작은 다음과 같습니다.

<div>
    <br>
</div>

그 명령으로

<p>
    <br>
</p>

이제 더 선형 적이므로 <br>필요한 것만 있으면됩니다.


div와 br을 사용하는 대신 enter를 누르면 p와 br이 브라우저에 나타납니다. 시도 해봐.
Ced

감사! 설명은 항상 도움이됩니다
jpaugh

@ jpaugh np, 나는 대답을 더 편집하여 더 잘 설명합니다.
Ced

이것은 파이어 폭스에서 작동하지 않습니다 (크롬과 파이어 폭스에서만 테스트되었습니다)
medBouzid

FireFox는 이제 defaultParagraphSeparator를 준수하도록 수정되었습니다. IMHO 이것은 모든 브라우저가 사양과 일관되고 인라인되도록하기 때문에이 답변을 최상으로 만듭니다. 그런 다음 P 태그가 편집 가능한 컨텐츠의 이전 텍스트 블록에서 여백 '간격'을 갖지 않게하려면 CSS를 사용하여 수정할 수 있습니다.
blackmamba

9

단일 태그를 넣거나 텍스트를 태그로 묶는 대신 shift+ enter를 사용하십시오 .enter<br><p>


9
+1 감사합니다. 알기 매우 편리하지만 책을 쓰는 고객이 있다면 ***
iConnor

1
콘텐츠를 붙여 넣기하는 경우이 도움이되지 않습니다
수직 동기화

5

contenteditable누를 때 작동 하는 방식은 enter브라우저, <div>웹킷 (크롬, 사파리) 및 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.browser더 이상 jQuery의 일부가 아닙니다.
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) { ... }
세바스찬 Sandqvist

5

<p>태그를 사용하는 대신 각 줄에 대해 별도의 태그를 사용할 수 있으며 <br>기본적으로 브라우저 호환성이 향상됩니다.

이렇게하려면 <p>contenteditable div 안에 기본 텍스트 가있는 태그를 넣으십시오 .

예를 들어,

<div contenteditable></div>

사용하다:

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

jsfiddle

Chrome, Firefox 및 Edge에서 테스트되었으며 두 번째는 각각 동일하게 작동합니다.

먼저 그러나, 크롬으로 된 div를 생성 파이어 폭스에서 줄 바꿈을 생성하고, 가장자리에있는 div를 생성 하고 커서 대신 다음 하나에 이동 현재 DIV의 시작 부분에 다시 배치됩니다.

Chrome, Firefox 및 Edge에서 테스트되었습니다.


이것은 실제로 나쁜 해결책은 아닙니다
AaronHS

5

핸드 헬드 단축키에 마우스 트랩을 사용하고 싶습니다 : https://craig.is/killing/mice

그런 다음 enterLineBreak 명령을 실행하여 enter 이벤트를 차단합니다 .

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.div( div일반적인 생각을 바로 잡기 위해 다른 코드를 넣어야 할 것입니다 )
Math chiller

4

스타일링 (Css)을 사용하여 문제를 해결합니다.

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

Firefox는 실제로 block element break를 추가하는
반면 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/


1
이것은 일부 사람들에게 도움이 될 수 있지만, 최종 HTML을 가져 contenteditable와서 다른 곳에서 사용하기 때문에 비 필수적인 마크 업에 대해 더 걱정 했습니다.
iConnor

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

먼저 우리는 모든 주요 사용자가 우리가 방지 다음을 누르면 입력 있는지 확인하기 위해 입력 캡처해야 <div>창조하고 우리는 우리 자신을 만들<br> 태그를 .

하나의 문제가 있는데, 커서를 만들 때 커서가 같은 위치에 머무르기 때문에 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>

한 가지 불편이 있습니다. 편집을 마치면 요소 <br>안에 끝이 포함될 수 있습니다 . 그러나 필요한 경우 코드를 추가하여 잘라낼 수 있습니다.

후행을 제거하려면이 답변을 확인하십시오. <br> https://stackoverflow.com/a/61237737/670839 하십시오.


이런 젠장? 실제로 나를 위해 일한 유일한 솔루션이 어떻게 페이지 아래쪽에 있습니까? 정말 고마워.
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/


입력 할 때 커서가 앞으로 이동하지 않습니다.
잭 루

이상합니다. 방금 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.