如何检测“ shift + enter”并在Textarea中生成新行?


145

当前,如果此人enter在文本区域内按下,则将提交表单。
好,我想要那个。

但是当他们输入shift+时enter,我希望textarea移至下一行:\n

我该如何JQuery尽可能简单地用普通JavaScript 做到这一点?


3
哦,我多么讨厌这种改变的行为... ^^你为什么要这么做?如果您用单词写字母,您是否希望它在按Enter键时将文本保存在文件中,还是应该以新行开头?
安德里亚斯(Andreas)

18
我正在建立一个聊天室。这就是Skype母鹿的坐姿。
TIMEX

10
检查e.shiftKey
泰国

6
您需要做的就是找到阻止Enter提交表单的代码,并检查事件的shiftKey属性。
Tim Down

3
对于文本字段中的新行,按ENTER键不会“更改”行为。驴的岁月,各种各样的事情都是人们期望的行为。几十年前,我在电子表格中输入文本时使用了它。
塞浦路斯放松,2016年

Answers:


81

更好地使用更简单的解决方案:

我建议使用以下Tim的解决方案更好:https : //stackoverflow.com/a/6015906/4031815


我的解决方案

我想你可以做这样的事情。

编辑:更改代码以工作,无论插入位置

代码的第一部分是获得插入符的位置。

参考:如何从头开始以字符为单位,在文本区域中插入符号(而非像素)的位置?

function getCaret(el) { 
    if (el.selectionStart) { 
        return el.selectionStart; 
    } else if (document.selection) { 
        el.focus();
        var r = document.selection.createRange(); 
        if (r == null) { 
            return 0;
        }
        var re = el.createTextRange(), rc = re.duplicate();
        re.moveToBookmark(r.getBookmark());
        rc.setEndPoint('EndToStart', re);
        return rc.text.length;
    }  
    return 0; 
}

然后在Shift+ Enter在一起时相应地替换textarea值,如果Enter单独按下则提交表格。

$('textarea').keyup(function (event) {
    if (event.keyCode == 13) {
        var content = this.value;  
        var caret = getCaret(this);          
        if(event.shiftKey){
            this.value = content.substring(0, caret - 1) + "\n" + content.substring(caret, content.length);
            event.stopPropagation();
        } else {
            this.value = content.substring(0, caret - 1) + content.substring(caret, content.length);
            $('form').submit();
        }
    }
});

这是一个演示


如果插入符不在文本区域内容的末尾,那将不起作用。
Tim Down

另外,还有一个错字(您是说event.keyCode == 13),我想您可能也想要event.preventDefault()而不是event.stopPropagation()
Tim Down

我改了 现在,无论插入位置如何,它都可以工作。和event.stopPropagation()我停下来的意思,他可能已经写入提交表单一些其他的代码。
Jishnu美联社

7
该插入符号位置功能有缺陷(请参阅我对链接的插入符号位置问题的评论和答案),并且无论如何您都不需要插入符号位置。在这里查看我的答案。Re event.stopPropagation(),这将防止事件在DOM上冒泡,但不会阻止按键执行其默认行为,即插入换行符(尽管实际上在keyup我的建议下event.preventDefault()也不会这样做)。
Tim Down

2
尽管它工作正常,但是它给出了carent未定义的错误,如果我将其更改为插入符号,它将添加2条新行
Aamir Mahmood 2012年

163

简单而优雅的解决方案:

首先,Enter除非您有脚本使之在文本区域内按下,否则不会提交该表单。这是用户期望的行为,建议不要更改它。但是,如果必须执行此操作,最简单的方法是找到使Enter表单提交并对其进行更改的脚本。该代码将类似于

if (evt.keyCode == 13) {
    form.submit();
}

...您可以将其更改为

if (evt.keyCode == 13 && !evt.shiftKey) {
    form.submit();
}

另一方面,如果由于某种原因无法访问此代码,则即使插入符号不在文本末尾,也需要执行以下操作以使其在所有主流浏览器中都能正常工作:

jsFiddle:http : //jsfiddle.net/zd3gA/1/

码:

function pasteIntoInput(el, text) {
    el.focus();
    if (typeof el.selectionStart == "number"
            && typeof el.selectionEnd == "number") {
        var val = el.value;
        var selStart = el.selectionStart;
        el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd);
        el.selectionEnd = el.selectionStart = selStart + text.length;
    } else if (typeof document.selection != "undefined") {
        var textRange = document.selection.createRange();
        textRange.text = text;
        textRange.collapse(false);
        textRange.select();
    }
}

function handleEnter(evt) {
    if (evt.keyCode == 13 && evt.shiftKey) {
        if (evt.type == "keypress") {
            pasteIntoInput(this, "\n");
        }
        evt.preventDefault();
    }
}

// Handle both keydown and keypress for Opera, which only allows default
// key action to be suppressed in keypress
$("#your_textarea_id").keydown(handleEnter).keypress(handleEnter);

42

这些答案大多使这一点变得复杂。为什么不这样尝试呢?

$("textarea").keypress(function(event) {
        if (event.keyCode == 13 && !event.shiftKey) {
         submitForm(); //Submit your form here
         return false;
         }
});

不会弄乱插入符号的位置或将换行符推入JS。基本上,如果按下Shift键,该功能将不会运行,因此允许Enter / Return键执行其正常功能。


这正是我想要的。谢谢。
大沽耀西

18

为什么不只是

$(".commentArea").keypress(function(e) {
    var textVal = $(this).val();
    if(e.which == 13 && e.shiftKey) {

    }
    else if (e.which == 13) {
       e.preventDefault(); //Stops enter from creating a new line
       this.form.submit(); //or ajax submit
    }
});

2
您可以只使用一种条件,例如(event.keyCode == 13 &&!event.shiftKey)。只是一个提示:如果您使用基因敲除js,则需要使textarea拳头不再聚焦以更新值:jQuery(this).blur();
贾斯汀

4

使用jQuery热键插件和此代码

jQuery(document).bind('keydown', 'shift+enter', 
         function (evt){ 
             $('textarea').val($('#textarea').val() + "\n");// use the right id here
             return true;
         }
);

3

如果有人使用AngularJS遇到相同的问题,这是使用ng-keyup的AngularJS解决方案。

ng-keyup="$event.keyCode == 13 && !$event.shiftKey && myFunc()"

3

这是使用ReactJS ES6的最简单方法

shift+ enter换行在任何位置

enter 受阻

class App extends React.Component {

 constructor(){
    super();
    this.state = {
      message: 'Enter is blocked'
    }
  }
  onKeyPress = (e) => {
     if (e.keyCode === 13 && e.shiftKey) {
        e.preventDefault();
        let start = e.target.selectionStart,
            end = e.target.selectionEnd;
        this.setState(prevState => ({ message:
            prevState.message.substring(0, start)
            + '\n' +
            prevState.message.substring(end)
        }),()=>{
            this.input.selectionStart = this.input.selectionEnd = start + 1;
        })
    }else if (e.keyCode === 13) { // block enter
      e.preventDefault();
    }
    
  };

  render(){
    return(
      <div>
      New line with shift enter at any position<br />
       <textarea 
       value={this.state.message}
       ref={(input)=> this.input = input}
       onChange={(e)=>this.setState({ message: e.target.value })}
       onKeyDown={this.onKeyPress}/>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='root'></div>


2

我发现此线程正在寻找一种控制Shift +任何键的方法。我将其他解决方案粘贴在一起,以使此组合功能完成我需要的工作。我希望它可以帮助其他人。

function () {
    return this.each(function () {
    $(this).keydown(function (e) {
        var key = e.charCode || e.keyCode || 0;
        // Shift + anything is not desired
        if (e.shiftKey) {
            return false;
        }
        // allow backspace, tab, delete, enter, arrows, numbers 
        //and keypad numbers ONLY
        // home, end, period, and numpad decimal
        return (
            key == 8 ||
            key == 9 ||
            key == 13 ||
            key == 46 ||
            key == 110 ||
            key == 190 ||
            (key >= 35 && key <= 40) ||
            (key >= 48 && key <= 57) ||
            (key >= 96 && key <= 105));
    });
});

1

如果有人仍然想知道如何在没有jQuery的情况下执行此操作。

的HTML

<textarea id="description"></textarea>

Java脚本

const textarea = document.getElementById('description');

textarea.addEventListener('keypress', (e) => {
    e.keyCode === 13 && !e.shiftKey && e.preventDefault(); 
})

香草JS

var textarea = document.getElementById('description');

textarea.addEventListener('keypress', function(e) {
    if(e.keyCode === 13 && !e.shiftKey) {
      e.preventDefault();
    }
})

1

我通过添加contenteditable true而不是使用textarea来使用div。

希望可以帮到您。

$("#your_textarea").on('keydown', function(e){//textarea keydown events
  if(e.key == "Enter")
  {
    if(e.shiftKey)//jump new line
    {
     // do nothing
    }
    else  // do sth,like send message or else
    {
       e.preventDefault();//cancell the deafult events
    }
  }
})

1

这对我有用!

$("#your_textarea").on('keydown', function(e){
    if(e.keyCode === 13 && !e.shiftKey) 
    {

          $('form').submit();

    }
});

0

ng-keyup在angularJS中使用指令,仅在按键时发送一条消息,Enter并且Shift+Enter只会换一行。

ng-keyup="($event.keyCode == 13&&!$event.shiftKey) ? sendMessage() : null"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.