阻止在ENTER上添加<div> - Chrome </div>

时间:2013-08-31 20:09:08

标签: javascript jquery google-chrome html contenteditable

我有一个contenteditable元素,每当我输入一些内容并点击ENTER时,它会创建一个新的<div>并将新的行文本放在那里。我不喜欢这一点。

是否可以防止这种情况发生,或至少只是用<br>替换它?

以下是演示 http://jsfiddle.net/jDvau/

注意:这不是firefox中的问题。

24 个答案:

答案 0 :(得分:147)

试试这个

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

<强> Demo Here

答案 1 :(得分:43)

只需更改CSS即可完成此操作:

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

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

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

答案 2 :(得分:31)

将样式display:inline-block;添加到contenteditable,它不会在Chrome中自动生成divpspan

答案 3 :(得分:20)

试试这个:

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

答案 4 :(得分:11)

使用 shift + 输入而不是输入,只需将<br>标记放入<p>或将文本换行于{{ 1}}标签。

答案 5 :(得分:11)

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

它会覆盖默认行为以改为使用段落。

在Chrome上,输入的默认行为是:

<div>
    <br>
</div>

使用该命令将会是

<p>
    <br>
</p>

现在它更加线性,很容易只需要<br>

答案 6 :(得分:8)

这在所有主流浏览器(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

答案 7 :(得分:6)

输入contenteditable的行为取决于浏览器,<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);
            }
        }
    });
}

我希望它会有所帮助,如果不是那么清楚,那对我的英语感到抱歉。

编辑:已删除的jQuery函数jQuery.browser

的更正

答案 8 :(得分:4)

我会使用样式(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/

的一个分支

答案 9 :(得分:4)

您可以为每一行添加单独的<p>代码,而不是使用<br>代码,并获得更好的浏览器兼容性。

要执行此操作,请在可信任的div中添加一个带有默认文本的<p>标记。

例如,而不是:

<div contenteditable></div>

使用:

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

Gitter chat

在Chrome,Firefox和Edge中进行测试,第二种方法在每种方法中都相同。

然而,第一个在Chrome中创建div,在Firefox中创建换行符,在Edge中创建div ,光标将放回当前div的开头,而不是移动到下一个之一。

在Chrome,Firefox和Edge中测试。

答案 10 :(得分:3)

尝试使用ckeditor。它还在SOF中提供类似这样的格式。

https://github.com/galetahub/ckeditor

答案 11 :(得分:3)

您可以使用<p>标记包装段落,例如它会显示在新行而不是div上 例如:
<div contenteditable="true"><p>Line</p></div>
插入新字符串后:
<div contenteditable="true"><p>Line</p><p>New Line</p></div>

答案 12 :(得分:2)

为div添加一个防止默认值

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

答案 13 :(得分:2)

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

答案 14 :(得分: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/

答案 15 :(得分: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();
        }
    }
});

<强> Fiddle

答案 16 :(得分:1)

防止在每个输入键上的内容可编辑Div中创建新Div:我找到的解决方案非常简单:

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

这个--- innerHTML内容阻止在每个输入键上的内容可编辑Div中创建新Div。

答案 17 :(得分: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/

答案 18 :(得分:1)

我遇到了同样的问题并找到了解决方案(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 :(得分:1)

当您嵌套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 :(得分:0)

我喜欢使用捕鼠器来处理热键: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");

答案 21 :(得分:0)

在W3C编辑器草案中,有一些有关在ContentEditable中添加状态的信息,为了防止浏览器在按Enter键时添加新元素,可以使用<div contentEditable="plaintext-only"></div>

References to Derived Types

Similar to the situation as described for pointers earlier, a base class reference can be
used to refer to an object of a derived class. The most common application of this is
found in function parameters. A base class reference parameter can receive objects of
the base class as well as any other type derived from that base.

答案 22 :(得分:0)

我使用数百个 <td> 元素来输入计算值,发现 Firefox 在输入时添加了一个 <div></div><br />,这并不酷。所以我用了这个onkeyup

$(document).on("keyup", '.first_td_col', function(e) {
    if (e.key === 'Enter' || e.keyCode === 13) {
       e.preventDefault();
       $(this).empty();

       return false;
    }
    // Do calculations if not enter
});

当然,这会清除 <td> 中的所有内容,甚至是用户的输入。但是通过显示 No enter please. 的消息,它解决了妨碍计算的不必要元素。

答案 23 :(得分:-1)

可以完全防止这种行为。

See this fiddle

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