当用户按下回车时,我希望光标移动到一个新行,但如果它们当前由两个标签缩进,则光标应保持缩进两个标签。
我已经实现了ignore tab事件来阻止焦点在页面内移动,所以我现在只是在寻找将标签级别保持在新行的逻辑。
if(e.keyCode === 13){
//Logic here
}
答案 0 :(得分:4)
$("textarea").keydown(function(e){
if(e.keyCode == 13){
// assuming 'this' is textarea
var cursorPos = this.selectionStart;
var curentLine = this.value.substr(0, this.selectionStart).split("\n").pop();
var indent = curentLine.match(/^\s*/)[0];
var value = this.value;
var textBefore = value.substring(0, cursorPos );
var textAfter = value.substring( cursorPos, value.length );
e.preventDefault(); // avoid creating a new line since we do it ourself
this.value = textBefore + "\n" + indent + textAfter;
setCaretPosition(this, cursorPos + indent.length + 1); // +1 is for the \n
}
});
function setCaretPosition(ctrl, pos)
{
if(ctrl.setSelectionRange)
{
ctrl.focus();
ctrl.setSelectionRange(pos,pos);
}
else if (ctrl.createTextRange) {
var range = ctrl.createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
}
答案 1 :(得分:0)
必须说基于一键的解决方案是晦涩难懂的,因为人们也喜欢粘贴文本。请改用input
事件。您可以像这样在jQuery中实现它:
$('textarea').on('input', function(e) {
var el = $(this);
var cur = $(this).prop('selectionStart'); // retrieve current caret position before setting value
var text = $(this).val();
var newText = text.replace(/^(.+)\t+/mg, '$1'); // remove intermediate tabs
newText = newText.replace(/^([^\t]*)$/mg, '\t\t$1'); // add two tabs in the beginning of each line
if (newText != text) { // If text changed...
$(this).val(newText); // finally set value
// and reset caret position shifted right by one symbol
$(this).prop('selectionStart', cur + 1);
$(this).prop('selectionEnd', cur + 1);
}
});
<textarea></textarea>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
顺便说一句,我懒得解释如何观察用户所需的制表符计数,所以这个只是在每行插入两个制表符。
答案 2 :(得分:0)
我通过使用execCommand 'insertText'
而不是修改textarea.value
改进了answer by Endless。
优势:
缺点:
$('textarea').on('keydown', function(e) {
if (e.which == 13) { // [ENTER] key
event.preventDefault() // We will add newline ourselves.
var start = this.selectionStart;
var currentLine = this.value.slice(0, start).split('\n').pop();
var newlineIndent = '\n' + currentLine.match(/^\s*/)[0];
if (!document.execCommand('insertText', false, newlineIndent)) {
// Add fallback for Firefox browser:
// Modify this.value and update cursor position as per solution by Endless.
}
}
});
<textarea style="width:99%;height:99px;"> I am indented by 8 spaces.
I am indented by a tab.</textarea>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>