admin管理员组文章数量:1135640
I would like a textarea that handles a situation of pressing tab key.
In default case if you press a tab key then focus leaves the textarea. But what about the situation when user wants to type tab key in textarea?
Can I catch this event and return focus to the textarea and add a tab to a current cursor position?
I would like a textarea that handles a situation of pressing tab key.
In default case if you press a tab key then focus leaves the textarea. But what about the situation when user wants to type tab key in textarea?
Can I catch this event and return focus to the textarea and add a tab to a current cursor position?
Share Improve this question edited Mar 22, 2013 at 8:43 sergzach asked May 26, 2011 at 14:54 sergzachsergzach 6,7547 gold badges51 silver badges86 bronze badges 2 |6 Answers
Reset to default 132You can: http://jsfiddle.net/sdDVf/8/.
$("textarea").keydown(function(e) {
if(e.keyCode === 9) { // tab was pressed
// get caret position/selection
var start = this.selectionStart;
var end = this.selectionEnd;
var $this = $(this);
var value = $this.val();
// set textarea value to: text before caret + tab + text after caret
$this.val(value.substring(0, start)
+ "\t"
+ value.substring(end));
// put caret at right position again (add one for the tab)
this.selectionStart = this.selectionEnd = start + 1;
// prevent the focus lose
e.preventDefault();
}
});
Here is a modified version of pimvdb's answer that doesn't need JQuery:
document.querySelector("textarea").addEventListener('keydown',function(e) {
if(e.keyCode === 9) { // tab was pressed
// get caret position/selection
var start = this.selectionStart;
var end = this.selectionEnd;
var target = e.target;
var value = target.value;
// set textarea value to: text before caret + tab + text after caret
target.value = value.substring(0, start)
+ "\t"
+ value.substring(end);
// put caret at right position again (add one for the tab)
this.selectionStart = this.selectionEnd = start + 1;
// prevent the focus lose
e.preventDefault();
}
},false);
I tested it in Firefox 21.0 and Chrome 27. Don't know if it works anywhere else.
Good god, all previous answers failed to provide the commonly decent (i.e. for programmers) tab control.
That is, a hitting TAB on selection of lines will indent those lines, and SHIFTTAB will un-indent them.
_edited (Nov 2016): keyCode replaced with charCode || keyCode, per KeyboardEvent.charCode - Web APIs | MDN
(function($) {
$.fn.enableSmartTab = function() {
var $this;
$this = $(this);
$this.keydown(function(e) {
var after, before, end, lastNewLine, changeLength, re, replace, selection, start, val;
if ((e.charCode === 9 || e.keyCode === 9) && !e.altKey && !e.ctrlKey && !e.metaKey) {
e.preventDefault();
start = this.selectionStart;
end = this.selectionEnd;
val = $this.val();
before = val.substring(0, start);
after = val.substring(end);
replace = true;
if (start !== end) {
selection = val.substring(start, end);
if (~selection.indexOf('\n')) {
replace = false;
changeLength = 0;
lastNewLine = before.lastIndexOf('\n');
if (!~lastNewLine) {
selection = before + selection;
changeLength = before.length;
before = '';
} else {
selection = before.substring(lastNewLine) + selection;
changeLength = before.length - lastNewLine;
before = before.substring(0, lastNewLine);
}
if (e.shiftKey) {
re = /(\n|^)(\t|[ ]{1,8})/g;
if (selection.match(re)) {
start--;
changeLength--;
}
selection = selection.replace(re, '$1');
} else {
selection = selection.replace(/(\n|^)/g, '$1\t');
start++;
changeLength++;
}
$this.val(before + selection + after);
this.selectionStart = start;
this.selectionEnd = start + selection.length - changeLength;
}
}
if (replace && !e.shiftKey) {
$this.val(before + '\t' + after);
this.selectionStart = this.selectionEnd = start + 1;
}
}
});
};
})(jQuery);
$(function() {
$("textarea").enableSmartTab();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea rows="10" cols="80">
/* Just some code to edit with our new superTab */
(function($) {
$.fn.enableSmartTab = function() {
$this = $(this);
$this.keydown(function(e) {
if ((e.charCode === 9 || e.keyCode === 9) && !e.metaKey && !e.ctrlKey && !e.altKey) {
e.preventDefault();
}
}
}
}
</textarea>
In Vanilla (Default) JS this would be:
var textareas = document.getElementsByTagName('textarea');
if ( textareas ) {
for ( var i = 0; i < textareas.length; i++ ) {
textareas[i].addEventListener( 'keydown', function ( e ) {
if ( e.which != 9 ) return;
var start = this.selectionStart;
var end = this.selectionEnd;
this.value = this.value.substr( 0, start ) + "\t" + this.value.substr( end );
this.selectionStart = this.selectionEnd = start + 1;
e.preventDefault();
return false;
});
}
}
textarea {
border: 1px solid #cfcfcf;
width: 100%;
margin-left: 0px;
top: 0px;
bottom: 0px;
position: absolute;
}
<textarea>
var x = 10;
var y = 10;
</textarea>
Found this while searching google. I made a really short one that can also indent and reverse indent selections of text:
jQ(document).on('keydown', 'textarea', function(e) {
if (e.keyCode !== 9) return;
var Z;
var S = this.selectionStart;
var E = Z = this.selectionEnd;
var A = this.value.slice(S, E);
A = A.split('\n');
if (!e.shiftKey)
for (var x in A) {
A[x] = '\t' + A[x];
Z++;
}
else
for (var x in A) {
if (A[x][0] == '\t')
A[x] = A[x].substr(1);
Z--;
}
A = A.join('\n');
this.value = this.value.slice(0, S) + A + this.value.slice(E);
this.selectionStart = S != E ? S : Z;;
this.selectionEnd = Z;
e.preventDefault();
});
Enable tabbing inside (multiple) textarea elements
Correcting @alexwells answer and enable a live demo
var textAreaArray = document.querySelectorAll("textarea");
for (var i = textAreaArray.length-1; i >=0;i--){
textAreaArray[i].addEventListener('keydown',function(e) {
if(e.keyCode === 9) { // tab was pressed
// get caret position/selection
var start = this.selectionStart;
var end = this.selectionEnd;
var target = e.target;
var value = target.value;
// set textarea value to: text before caret + tab + text after caret
target.value = value.substring(0, start)
+ "\t"
+ value.substring(end);
// put caret at right position again (add one for the tab)
this.selectionStart = this.selectionEnd = start + 1;
// prevent the focus lose
e.preventDefault();
}
},false);
}
<textarea rows="10" cols="80"></textarea>
<textarea rows="10" cols="80"></textarea>
本文标签: javascriptHow to handle lttabgt in textareaStack Overflow
版权声明:本文标题:javascript - How to handle <tab> in textarea? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736935701a1956939.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
indent-textarea
– fregante Commented Dec 15, 2019 at 21:07