jQuery 防止 contenteditable 在 ENTER 上添加 <div> - Chrome

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18552336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 21:56:04  来源:igfitidea点击:

Prevent contenteditable adding <div> on ENTER - Chrome

javascriptjquerygoogle-chromehtmlcontenteditable

提问by iConnor

I have a contenteditableelement, and whenever I type some stuff and hit ENTERit creates a new <div>and places the new line text in there. I don't like this one little bit.

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

Is it possible to prevent this from happening or at least just replace it with a <br>?

是否有可能防止这种情况发生或至少将其替换为<br>?

Here is demo http://jsfiddle.net/jDvau/

这是演示http://jsfiddle.net/jDvau/

Note: This is not an issue in firefox.

注意:这在 Firefox 中不是问题。

回答by Ram G Athreya

Try this:

尝试这个:

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

Click here for demo

单击此处进行演示

回答by airi

You can do this with just a CSS change:

您只需更改 CSS 即可做到这一点:

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

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

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

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

回答by Le Tung Anh

Add style display:inline-block;to contenteditable, it will not generate div, pand spanautomatically in Chrome.

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

回答by Ced

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

It overrides the default behavior to have paragraph instead.

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

On chrome the default behavior on enter is:

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

<div>
    <br>
</div>

With that command it is gonna be

有了那个命令,它会是

<p>
    <br>
</p>

Now that it's more linear across it's easy to have only <br>would you need to.

现在它更线性了,只要<br>你需要,就很容易拥有。

回答by Andrew

Try this:

尝试这个:

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

http://jsfiddle.net/rooseve/jDvau/3/

回答by Blake Plumb

Use shift+enterinstead of enterto just put a single <br>tag in or wrap your text in <p>tags.

使用shift+enter而不是enter只放置一个<br>标签或将文本包裹在<p>标签中。

回答by Elie

The way that contenteditablebehaves when you press enterdepends on browsers, the <div>happens on webkit (chrome, safari) and IE.

contenteditable按下时的行为方式enter取决于浏览器,<div>发生在 webkit(chrome、safari)和 IE 上。

I struggled with this few month ago and I corrected it this way :

几个月前我为此苦苦挣扎,并以这种方式纠正了它:

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

I hope it will help, and sorry for my english if it's not as clear as needed.

我希望它会有所帮助,如果我的英语不够清晰,请见谅。

EDIT: Correction of removed jQuery function jQuery.browser

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

回答by Josh Powlison

You can have separate <p>tags for each line rather than using <br>tags and gain greater browser compatibility out of the box.

您可以<p>为每一行设置单独的标签,而不是使用<br>标签,并且开箱即用地获得更大的浏览器兼容性。

To do this, put a <p>tag with some default text inside of the contenteditable div.

为此,请<p>在 contenteditable div 内放置一个带有一些默认文本的标签。

For example, instead of:

例如,而不是:

<div contenteditable></div>

Use:

用:

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

jsfiddle

提琴手

Tested in Chrome, Firefox, and Edge, and the second works the same in each.

在 Chrome、Firefox 和 Edge 中进行了测试,第二个在每个中都相同。

The first, however, creates divs in Chrome, creates line breaks in Firefox, and in Edge creates divs andthe cursor is put back at the beginning of the current div instead of moving into the next one.

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

Tested in Chrome, Firefox, and Edge.

在 Chrome、Firefox 和 Edge 中测试。

回答by Gauss

I like to use Mousetrap for handlling hotkeys: https://craig.is/killing/mice

我喜欢使用捕鼠器来处理热键:https://craig.is/killing/mice

Then, I just intercept the enter event, executing a command insertLineBreak:

然后,我只是拦截 enter 事件,执行命令insertLineBreak

Mousetrap.bindGlobal('enter', (e)=>{
  window.document.execCommand('insertLineBreak', false, null);
  e.preventDefault();
});

All commands: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

所有命令:https: //developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

It works using Chrome 75 and the following editable element:

它使用 Chrome 75 和以下可编辑元素工作:

<pre contenteditable="true"></pre>

It's also possible to use insertHTML:

也可以使用insertHTML

window.document.execCommand('insertHTML', false, "\n");

回答by skerit

The inserHTMLcommand solution does some weird things when you have nested contenteditableelements.

inserHTML当您有嵌套contenteditable元素时,命令解决方案会做一些奇怪的事情。

I took some ideas from multiple answers here, and this seems to suit my needs for now:

我从这里的多个答案中汲取了一些想法,这似乎适合我现在的需求:

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