避免contentEditable中的行/段落换行

72
当在Firefox中使用contentEditable时,是否有一种方法可以防止用户通过按Enter或Shift + Enter插入段落或换行符?
13个回答

87

你可以为contentEditable字段附加keydown或keypress事件处理程序,并且如果按键代码识别为enter(或shift+enter),则取消事件。

这将在焦点位于contentEditable字段中时完全禁用enter / shift + enter。

如果使用jQuery,可以使用类似以下的代码:

$("#idContentEditable").keypress(function(e){ return e.which != 13; });

...这将返回false并取消回车键的按键事件。


57
请注意,当将带有换行符的文本复制粘贴到可编辑区域时,此方法将无效。 - Mathias Bynens
1
不包括粘贴(从剪贴板)或拖放内容的情况。 - Kafoso
在处理页面上的多个contenteditable元素时非常有用,而不仅仅是一个。 - Systems Rebooter
@SystemsRebooter 只需在不同的元素上执行或使用循环。 - RixTheTyrunt

50

使用纯JavaScript也可以做到这一点,而且工作量相同:

document.getElementById('idContentEditable').addEventListener('keypress', (evt) => {
    if (evt.which === 13) {
        evt.preventDefault();
    }
});

对于最简单的事情,您不应该使用jQuery。此外,您可能希望使用“key”而不是“which”:https://developer.mozilla.org/en-US/docs/Web/Events/keypress

更新,因为keypress已弃用:

document.getElementById('idContentEditable').addEventListener('keydown', (evt) => {
    if (evt.keyCode === 13) {
        evt.preventDefault();
    }
});

5
我同意,并且顺便说一下,我在引发这个问题的项目中没有使用 JQuery。让我有点烦恼的是,SO 上的 JavaScript 回答通常假定每个人都在使用 JQuery,但另一方面,初学者极有可能在使用 JQuery,其他人也能够将答案翻译为自己喜欢的库或不使用库的方式 :)。 - Daniel Cassidy
3
我认为初学者总是试图把所有东西都用jQuery解决,这是一个很大的问题。他们甚至不再真正学习原生的JavaScript了。 - andyrandy
3
现在 keyCode 也已经被弃用了,所以请使用 evt.key === "Enter"。无法保证向后兼容性。文档链接 - cbednarski
而在jQuery中,可以这样写: $(".<class_name>").keypress(function(e) { if (e.which === 13) e.preventDefault(); }); - OritK
有一个错别字:evt.preventDefault 应该是 event.preventDefault!此外,lambda语法并不适用于每个浏览器。这段代码对我很有效: name.addEventListener('keydown',function(event){ if(event.keyCode === 13){ event.preventDefault(); } }); - cskwg
你是指箭头函数吗?因为它在所有重要的浏览器中都可以使用:https://caniuse.com/#feat=arrow-functions - IE11已经不再真正相关了。不过你关于错别字的说法是正确的,感谢指出! - andyrandy

23

添加以下CSS规则以隐藏换行符。这仅是一个样式设置,您应该添加一些事件处理程序来防止插入换行符:

.your_editable br {
    display: none
}

14
Chrome也会插入一些<DIV>,因此在此之前可能需要添加.your_editable * { display: inline } - Eugene Ryabtsev
确实很烦人 - RixTheTyrunt
多么独特的方法。我遇到了一个无关的问题,即自定义样式文本由于Chrome插入的换行符被删除而上移。有趣的是,通过从开发工具中刷新样式表,问题得到了解决。在找到你的解决方案之前,我已经失去了希望。现在它可以正常工作了。 - McRaZick

12

除了添加换行符外,浏览器还会添加其他标签和样式(当您粘贴文本时,浏览器还会附加您粘贴的文本样式)。

下面的代码包含所有内容。

  • When you press enter, no line breaks will be added.
  • When you paste text, all elements added by the browser are stripped from the text.

    $('[contenteditable]').on('paste', function(e) {
        //strips elements added to the editable tag when pasting
        var $self = $(this);
        setTimeout(function() {$self.html($self.text());}, 0);
    }).on('keypress', function(e) {
         //ignores enter key
         return e.which != 13;
    });
    

点击此处查看一个实时示例


1
从审核队列中:可以请您在您的源代码周围添加一些上下文吗?仅有代码的答案很难理解。如果您能在帖子中添加更多信息,将有助于提问者和未来的读者。 - RBT

7
另一种选择是允许输入换行符,但在失焦时将其删除。这种方法的优点是处理粘贴内容更加方便。您的用户可能会喜欢或讨厌它(取决于您的用户)。
function handle_blur(evt){
  var elt=evt.target; elt.innerText=elt.innerText.replace(/\n/g,' ');
}

然后,在HTML中:
<span onblur="handle_blur(event)" contenteditable>editable text</span>

6
如果您正在使用 JQuery 框架,您可以使用 on 方法进行设置,即使该元素在后来添加,它也能让您在所有元素上达到所需的行为。
$(document).on('keypress', '.YourClass', function(e){
    return e.which != 13; 
});   

5

添加:

display: flex;

关于可编辑的HTML元素

6
请为您的解决方案添加适当的解释,以说明它如何回答问题。 - Jens
简单而完美! - David Chavez
太棒了,完美无缺! - EaBengaluru
使用Shift+Enter时无法正常工作。 - Just Mohit
2
这是如何工作的:当您在可编辑元素中添加换行符时,浏览器会自动将您的行包装在div元素内。当换行时,它会自动添加一个div元素以开始当前新行。通过使用display: flex,您可以使DIV水平显示在同一行中,而不像默认情况下应用的display: block。这并不会阻止添加新行。它只是使它们直接相邻地出现。您可以通过使用DevTools或按shift+enter来确认此行为。 - Just Mohit

3

我来到这里搜索同样的问题,惊讶地发现这是一个相当简单的解决方案,使用经过验证的Event.preventDefault()方法即可。

const input = document.getElementById('input');

input.addEventListener('keypress', (e) => {
  if (e.which === 13) e.preventDefault();
});
<div contenteditable="true" id="input">
  You can edit me, just click on me and start typing.
  However, you can't add any line breaks by pressing enter.
</div>


这正是我的答案,比你早三年 ;) - andyrandy
啊,原来如此,不确定为什么我回答了这个问题,也许它没有被接受的答案,而且我没有看到你的回复;然而,有一个关键的区别,我将元素分配给一个常量,以使代码更易读 #惊人 - AnonymousSB

3
$("#idContentEditable").keypress(function(e){ return e.which != 13; });

Kamens 提出的解决方案在 Opera 中不起作用,您应该将事件附加到文档上。
/**
 * Pass false to enable
 */
var disableEnterKey = function(){
    var disabled = false;

    // Keypress event doesn't get fired when assigned to element in Opera
    $(document).keypress(function(e){
        if (disabled) return e.which != 13;
    });                 

    return function(flag){
        disabled = (flag !== undefined) ? flag : true;
    }
}();    

3
如果您想针对所有contentEditable字段进行定位,请使用以下方法:
$('[contenteditable]').keypress(function(e){ return e.which != 13; });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接