it-roy-ru.com

Предотвратить добавление <div> на ENTER - Chrome

У меня есть элемент contenteditable, и всякий раз, когда я набираю что-то и нажимаю ENTER, он создает новый <div> и помещает туда текст новой строки. Мне немного не нравится это. 

Можно ли предотвратить это или хотя бы просто заменить его на <br>?

Вот демо http://jsfiddle.net/jDvau/

Примечание: Это не проблема в Firefox.

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

Демо Здесь

144
Ram G Athreya

Вы можете сделать это, просто изменив CSS:

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

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

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

41
airi

Добавьте стиль display:inline-block; в contenteditable, он не будет автоматически генерировать div, p и span в Chrome.

29
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

Использование shift+enter вместо enter просто вставить один тег <br> или обернуть текст в теги <p>.

11
Blake Plumb
document.execCommand('defaultParagraphSeparator', false, 'p');

Он переопределяет поведение по умолчанию, чтобы иметь вместо абзаца.

В Chrome стандартное поведение при вводе:

<div>
    <br>
</div>

С этой командой это будет

<p>
    <br>
</p>

Теперь, когда он более линейный, легко иметь только <br>.

10
Ced

То, как contenteditable ведет себя при нажатии enter В зависимости от браузеров, <div> происходит в веб-наборе (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 дает divs отступы 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

Вы можете использовать отдельные теги <p> для каждой строки вместо использования тегов <br> и получить большую совместимость с браузером из коробки.

Для этого поместите тег <p> с текстом по умолчанию внутри contenteditable div.

Например, вместо:

<div contenteditable></div>

Использование:

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

jsfiddle

Протестировано в Chrome, Firefox и Edge, и второе работает одинаково в каждом.

Первый, однако, создает div в Chrome, создает разрывы строк в Firefox, а в Edge создает 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

Сначала нам нужно захватить каждый ключевой пользовательский ввод, чтобы увидеть, нажата ли ввод, затем мы предотвращаем создание <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();
        }
    }
});

Fiddle

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

добавить предотвращение по умолчанию в div

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

Это браузерный редактор 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
Fábio Zangirolami

Еще один способ сделать это

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

Предотвратить создание нового Div в редактируемом содержимом Div для каждой клавиши ввода. Решение, которое я нашел, очень просто:

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

Это --- содержимое innerHTML предотвращает создание нового Div в содержимом, редактируемом Div для каждой клавиши ввода.

1
DrShyam Babu Gupta

Решение команды 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;
}
0
skerit