如何检测"shift+enter"并在文本区域中生成新行?



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

但是当他们键入 shift + enter 时,我希望文本区域移动到下一行:n

如何在JQuery或普通 JavaScript 中尽可能简单地做到这一点?

简单而优雅的解决方案:

首先,在文本区域内按 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);

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

蒂姆下面的解决方案更好,我建议使用它: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; 
}

然后相应地替换文本区域值时 转移 + 一起输入 ,如果单独按 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();
        }
    }
});

这是一个演示

这些答案中的大多数都使这一点过于复杂。 为什么不试试这种方式呢?

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

无需弄乱插入符号位置或将换行符推入 JS。 基本上,如果按下 shift 键,该功能将不会运行,因此允许输入/返回键执行其正常功能。

为什么不只是

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

使用 jQuery 热键插件和这段代码

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

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

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

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

shift+在任何位置输入新行

输入已阻止

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>

我发现这个线程正在寻找一种控制 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));
    });
});

我通过添加内容可编辑的 true 而不是使用文本区域来使用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
    }
  }
})
另一种

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

组件内部.html

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

内部组件.ts

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

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

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 += 'rn';
  }
})

和 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>

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

.HTML

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

爪哇语

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();
    }
})
这对

我有用!

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

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

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

我知道这是一个古老的问题,但我想抛出一个隐含的观察结果,如果使用 Shift + A-Z,有些人可能要考虑。

document.onkeydown = (k) => {
  if (k.key === "Q") {
    console.log("Shift + Q");
  }
}

您可以按大小写检查密钥,例如 "Q""q" 。如果做前者,那么暗示Shift被按下,因为它是一个大写字母。

这里涉及功能的一个错误是CapsLock是否打开。但是,如果你像我一样,在个人脚本中使用它,那么这没什么大不了的。

另一个潜在的好处可能是"隐藏"一个明确的条件,寻找要按下的Shift键。不过,诚然,这是一个半生不熟的建议。

一些复杂的解决方案不需要发送n.
在事件keydown只需返回键13如果按下 shift 键

​$("#mytestarea").keydown(function (e) {
   ​
   ​if (e.keyCode == 13) { // Enter pressed
       //No shift or alt or ctrl
       ​if (!e.shiftKey && !e.altKey && !e.ctrlKey) {
           ​SendMsg(); // or submit or what you wan't
       ​}
       ​if (e.shiftKey) {
           //replace the shift for keycode 13 only
           ​return 13;
       ​}
                   ​
       ​//method to prevent from default behaviour
       ​e.preventDefault();
   ​}
});
<input type="text" onkeydown="handleMessageKeydown" /> 

或一些内容可编辑的元素:

<div contenteditable="true" onchange="handleMessageKeydown" />
handleMessageKeydown(e) {
      if (!e.shiftKey && e.key === "Enter") {
          e.preventDefault()
          sendMessage()
      }
 }

如果按 Shift 键,那么它将创建新行,否则它将落在上面给出的 if 条件内。在 if 条件中,e.preventDefault() 行是最重要的。对于 keydown 事件处理程序,e.preventDefault() 停止运行该操作,以便您可以执行自己的操作,例如将消息发送到服务器等。

这是

最好的方法

  if (e.key === 'Enter') {
    console.log('enter');
  }
  if (e.key === 'Enter' && e.ctrlKey) {
    console.log('clt+enter');
  }
  if (e.key === 'Enter' && e.ctrlKey && e.shiftKey) {
    console.log('clt+shift+enter');
  }

最新更新