如何检测“shift+enter”并在 Textarea 中生成新行?
Posted
技术标签:
【中文标题】如何检测“shift+enter”并在 Textarea 中生成新行?【英文标题】:How do I detect "shift+enter" and generate a new line in Textarea? 【发布时间】:2011-08-26 06:16:28 【问题描述】:目前,如果用户在文本区域内按enter,表单将提交。 很好,我想要那个。
但是当他们键入 shift + enter 时,我希望 textarea 移动到下一行:\n
如何在 JQuery
或纯 javascript 中尽可能简单地做到这一点?
【问题讨论】:
您能告诉我们您当前的代码吗? 我正在建立一个聊天室。 Skype 就是这样坐的。 检查e.shiftKey
。
您需要做的就是找到阻止 Enter 提交表单的代码并检查事件的 shiftKey
属性。
Shift ENTER 在文本字段中换行不是“更改”行为。这是驴子多年以来的预期行为,对于各种各样的事情。几十年前我在电子表格中输入文本时使用过它。
【参考方案1】:
简单优雅的解决方案:
首先,在 textarea 中按 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);
【讨论】:
【参考方案2】:最好使用更简单的解决方案:
以下 Tim 的解决方案更好,我建议使用它: https://***.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 + 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();
);
这是demo
【讨论】:
如果插入符号不在文本区域内容的末尾,那将不起作用。 另外,还有一个错字(你的意思是event.keyCode == 13
),我想你可能还想要event.preventDefault()
而不是event.stopPropagation()
。
我改了。现在无论插入符号位置如何,它都可以工作。通过event.stopPropagation()
,我的意思是停止他可能为提交表单而编写的一些其他代码。
插入符号位置功能存在缺陷(请参阅我对链接插入符号位置问题的评论和回答),无论如何您都不需要插入符号位置来执行此操作。在这里查看我的答案。回复event.stopPropagation()
,这将防止事件在DOM 中进一步冒泡,但不会阻止按键执行其插入换行符的默认操作(尽管实际上在keyup
我对event.preventDefault()
的建议不会那样做要么)。
虽然它工作正常,但它给出了 carent
未定义的错误,如果我将它更改为插入符号,它会添加 2 个新行【参考方案3】:
这些答案中的大多数都过于复杂了。为什么不这样尝试呢?
$("textarea").keypress(function(event)
if (event.keyCode == 13 && !event.shiftKey)
submitForm(); //Submit your form here
return false;
);
没有乱七八糟的插入符号位置或推线插入 JS。基本上,如果按下 shift 键,该功能将不会运行,因此允许 enter/return 键执行其正常功能。
【讨论】:
这正是我想要的。谢谢。【参考方案4】:为什么不直接
$(".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
);
【讨论】:
您可以只使用一种条件,例如 (event.keyCode == 13 && !event.shiftKey)。提示:如果你使用knockoutjs,你需要将textarea拳头散开来更新值:jQuery(this).blur(); 你是“停止进入创建新行”的人:)【参考方案5】:如果有人在使用 AngularJS 时遇到同样的问题,这里是使用 ng-keyup 的 AngularJS 解决方案。
ng-keyup="$event.keyCode == 13 && !$event.shiftKey && myFunc()"
【讨论】:
【参考方案6】:使用jQuery hotkeys 插件和此代码
jQuery(document).bind('keydown', 'shift+enter',
function (evt)
$('textarea').val($('#textarea').val() + "\n");// use the right id here
return true;
);
【讨论】:
【参考方案7】:这里使用 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>
【讨论】:
【参考方案8】:我发现这个帖子正在寻找一种控制 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));
);
);
【讨论】:
【参考方案9】:我通过添加 contenteditable true 来使用 div,而不是使用 textarea。
希望能帮到你。
$("#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
)
【讨论】:
【参考方案10】: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');
【讨论】:
【参考方案11】:如果有人仍然想知道如何在没有 jQuery 的情况下做到这一点。
HTML
<textarea id="description"></textarea>
Javascript
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();
)
【讨论】:
【参考方案12】:这对我有用!
$("#your_textarea").on('keydown', function(e)
if(e.keyCode === 13 && !e.shiftKey)
$('form').submit();
);
【讨论】:
【参考方案13】:和 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>
【讨论】:
【参考方案14】:在 angularJS 中使用ng-keyup
指令,仅在按下Enter
键时发送消息,Shift+Enter
将换行。
ng-keyup="($event.keyCode == 13&&!$event.shiftKey) ? sendMessage() : null"
【讨论】:
【参考方案15】:这段代码非常适合我的目的
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';
)
【讨论】:
【参考方案16】:我知道这是一个老问题,但我想抛出一个隐含的观察,如果使用 Shift
+ A-Z
,有些人可能会考虑。
document.onkeydown = (k) =>
if (k.key === "Q")
console.log("Shift + Q");
您可以按大小写检查密钥,例如"Q"
或"q"
。如果是前者,则暗示 Shift
被按下,因为它是一个大写字母。
这里涉及功能的一个错误是CapsLock
是否打开。但是,如果您像我一样在个人脚本中使用它,那么这并不是什么大不了的事。
另一个潜在的好处可能是“隐藏”一个明确的条件,寻找要按下的Shift
键。不过,这无疑是一个不成熟的建议。
【讨论】:
【参考方案17】:一些复杂的解决方案发送\n
是不必要的。
在 keydown
事件上,如果按下 shift 键,只需返回键 13
$("#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();
);
【讨论】:
【参考方案18】:<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() 停止运行操作,以便您可以执行自己的操作,例如向服务器发送消息等。
【讨论】:
以上是关于如何检测“shift+enter”并在 Textarea 中生成新行?的主要内容,如果未能解决你的问题,请参考以下文章
Adobe Animate (Flash):在调试 (Ctrl+Shift+Enter) 中违反安全沙箱,但在测试中违反 (Ctrl+Enter)