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

时间:2011-05-16 08:19:13

标签: javascript jquery html css

目前,如果此人在文本区域内按输入,表单将提交。
好,我想要那个。

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

如何在JQuery或普通JavaScript中尽可能简单地执行此操作?

15 个答案:

答案 0 :(得分:132)

简单&优雅的解决方案:

首先,在textarea中按 Enter 不会提交表单,除非您有脚本来执行此操作。这是用户期望的行为,我建议不要改变它。但是,如果必须这样做,最简单的方法是找到正在制作 Enter 的脚本提交表单并进行更改。代码将具有类似

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

...你可以把它改成

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

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

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

答案 1 :(得分:72)

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

下面蒂姆的解决方案更好我建议使用它: https://stackoverflow.com/a/6015906/4031815


我的解决方案

我认为你可以做这样的事情......

编辑:无论插入位置如何,都将代码更改为

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

参考:How to get the caret column (not pixels) position in a textarea, in characters, from the start?

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 + 一起输入时相应地替换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();
        }
    }
});

这是demo

答案 2 :(得分:37)

这些答案大多过于复杂。为什么不这样试试?

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

没有乱七八糟的位置或推断JS线。基本上,如果按下shift键,该功能将不会运行,因此允许输入/返回键执行其正常功能。

答案 3 :(得分:16)

为什么不

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

答案 4 :(得分:3)

使用jQuery hotkeys插件和此代码

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

答案 5 :(得分:3)

如果有人使用AngularJS遇到同样的问题,这是一个使用http://leafletjs.com/的AngularJS解决方案。

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

答案 6 :(得分:2)

使用Angular2 +检测Shift + Enter键的另一种解决方案

内部Component.html

<input type="text" (keydown.shift.enter)="newLine($event)">

内部Component.ts

newLine(event){
      if(event.keyCode==13 && event.shiftKey){
        alert('Shift+Enter key Pressed');
      }
  }

答案 7 :(得分:1)

我发现这个帖子正在寻找控制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));
    });
});

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

答案 9 :(得分:1)

这对我有用!

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

          $('form').submit();

    }
});

答案 10 :(得分:1)

和 jquery 示例

$.fn.pressEnter = function(fn) {
    return this.each(function() {  
        $(this).bind('enterPress', fn);
        $(this).keyup(function(e){
        
            /*When SHIFT return false*/
            if(e.shiftKey==true) return false;

            if(e.keyCode == 13)
            {
              /*You can do the thing on ENTER*/
              alert('Enter press');
            }

        })
    });  
}; 
$('.exampleClass').pressEnter(function(){})
div{
  width:200px;
  height:100px;
  border:solid 1px #000;
  float:left;
}
textarea{
  width:200px;
  height:100px;
  border:solid 1px #000;
  float:right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="exampleClass" contenteditable></div>

<textarea  class="exampleClass"></textarea>

答案 11 :(得分:0)

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

ng-keyup="($event.keyCode == 13&&!$event.shiftKey) ? sendMessage() : null"

答案 12 :(得分:0)

如果有人仍然想知道如何在没有jQuery的情况下这样做。

HTML

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

的Javascript

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

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

Vanilla JS

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

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

答案 13 :(得分:0)

对于使用ReactJS ES6的人来说,这是最简单的方法

shift + 输入新行

输入已屏蔽

&#13;
&#13;
class App extends React.Component {

 constructor(){
    super();
    this.state = {
      message: 'Enter is blocked'
    }
  }
  onKeyPress = (e) => {
  
    if (e.keyCode === 13) { // block enter
      e.preventDefault();
    }
    if (e.keyCode === 13 && e.shiftKey) {
      e.preventDefault();
      this.setState(prevState => ({ message: prevState.message+'\n' }))
    }
  };

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

ReactDOM.render(<App />, document.getElementById('root'));
&#13;
<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>
&#13;
&#13;
&#13;

答案 14 :(得分:0)

这段代码非常适合我的目的

document.getElementById('text').addEventListener('keypress', (e) => {
  if (e.key == 'Enter' && !e.shiftKey) {
    e.preventDefault()
    console.log('your code goes here');
  }
  if (e.key == 'Enter' && e.shiftKey) {
    e.preventDefault();
    console.log("insertLineBreak");
    const txtArea = document.getElementById('text');
    txtArea.value += '\r\n';
  }
})