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

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

Можно ли предотвратить это или, по крайней мере, просто заменить его на <br>?

Вот демонстрация http://jsfiddle.net/jDvau/

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

Ответ 1

Попробуйте это

$('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;
    }
  });

Демо здесь

Ответ 2

Вы можете сделать это только с помощью CSS:

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

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

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

Ответ 3

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

Ответ 4

Попробуйте следующее:

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

Ответ 5

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

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

В хроме по умолчанию поведение по умолчанию:

<div>
    <br>
</div>

С помощью этой команды он будет

<p>
    <br>
</p>

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

Ответ 6

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

Ответ 7

Способ, которым 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);
            }
        }
    });
}

Я надеюсь, что это поможет, и извините за мой английский, если это не так ясно, как нужно.

EDIT: Исправление удаленной функции jQuery jQuery.browser

Ответ 8

Я бы использовал стиль (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/

Ответ 9

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

Чтобы сделать это, поместите тег <p> с некоторым текстом по умолчанию внутри содержащего контент div.

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

<div contenteditable></div>

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

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

jsfiddle

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

Первое, однако, создает div в Chrome, создает разрывы строк в Firefox, а в Edge создает divs, а курсор помещается в начало текущего div вместо перехода в следующий.

Протестировано в Chrome, Firefox и Edge.

Ответ 10

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

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

Ответ 11

Попробуйте использовать ckeditor. Он также обеспечивает форматирование, подобное этому в SOF.

https://github.com/galetahub/ckeditor

Ответ 12

Вы можете обернуть ваши абзацы тегом <p>, например, он будет использовать новую строку вместо div Пример:
<div contenteditable="true"><p>Line</p></div>
После вставки новой строки:
<div contenteditable="true"><p>Line</p><p>New Line</p></div>

Ответ 13

Сначала нам нужно захватить каждый пользователь, который вводит ключ, чтобы увидеть, нажат ли ввод, а затем мы предотвращаем создание <div>, и мы создаем собственный тег <br>.

Там одна проблема, когда мы ее создаем, наш курсор остается в том же положении, поэтому мы используем 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

Ответ 14

Это редактор 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/

Ответ 15

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');.

Ответ 16

Другой способ сделать это

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

Ответ 17

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

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

Этот --- innerHTML контент предотвращает создание нового Div в содержимом editable Div для каждого ключа ввода.

Ответ 18

У меня была эта же проблема и я нашел решение (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/

Ответ 19

inserHTML команды 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;
}

Ответ 20

Мне нравится использовать Mousetrap для работы с горячими клавишами: https://craig.is/killing/mice

Затем я просто перехватываю событие ввода, выполняя команду 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");

Ответ 21

Можно полностью предотвратить это поведение.

См. эту скрипту

$('<div class="temp-contenteditable-el" contenteditable="true"></div>').appendTo('body').focus().remove();