Html 使用制表符在 textarea 中缩进
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6637341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use tab to indent in textarea
提问by user780483
I have a simple html textarea on my side. Right now if you click tab in it, it goes to the next field. I would like to make the tab button indent a few spaces instead. How can I do this? Thanks.
我身边有一个简单的 html textarea。现在,如果您单击其中的选项卡,它将转到下一个字段。我想让标签按钮缩进几个空格。我怎样才能做到这一点?谢谢。
回答by kasdega
Borrowing heavily from other answers for similar questions (posted below)...
从类似问题的其他答案中大量借用(在下面发布)......
$(document).delegate('#textbox', 'keydown', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
// set textarea value to: text before caret + tab + text after caret
$(this).val($(this).val().substring(0, start)
+ "\t"
+ $(this).val().substring(end));
// put caret at right position again
this.selectionStart =
this.selectionEnd = start + 1;
}
});
jQuery: How to capture the TAB keypress within a Textbox
回答by user1949974
var textareas = document.getElementsByTagName('textarea');
var count = textareas.length;
for(var i=0;i<count;i++){
textareas[i].onkeydown = function(e){
if(e.keyCode==9 || e.which==9){
e.preventDefault();
var s = this.selectionStart;
this.value = this.value.substring(0,this.selectionStart) + "\t" + this.value.substring(this.selectionEnd);
this.selectionEnd = s+1;
}
}
}
This solution does not require jQuery and will enable tab functionality on all textareas on a page.
此解决方案不需要 jQuery,并且将在页面上的所有文本区域上启用选项卡功能。
回答by Will Martin
As others have written, you can use JavaScript to capture the event, prevent the default action (so that the cursor does not shift focus) and insert a tab character.
正如其他人所写,您可以使用 JavaScript 来捕获事件,阻止默认操作(使光标不会移动焦点)并插入制表符。
But, disabling the default behavior makes it impossible to move the focus out of the text area without using a mouse. Blind users interact with web pages using the keyboard and nothing else -- they can't see the mouse pointer to do anything useful with it, so it's keyboard or nothing. The tab key is the primary way to navigate the document, and especially forms. Overriding the default behavior of the tab key will make it impossible for blind users to move the focus to the next form element.
但是,禁用默认行为将无法在不使用鼠标的情况下将焦点移出文本区域。盲人用户使用键盘与网页交互,没有别的——他们看不到鼠标指针来做任何有用的事情,所以它是键盘还是什么都没有。Tab 键是导航文档,尤其是表单的主要方式。覆盖 tab 键的默认行为将使盲人用户无法将焦点移动到下一个表单元素。
So, if you're writing a web site for a broad audience, I'd recommend against doing this without a compellingreason, and provide some kind of alternative for blind users that doesn't trap them in the textarea.
因此,如果您正在为广大受众编写网站,我建议您在没有令人信服的理由的情况下不要这样做,并为盲人用户提供某种替代方案,以免将他们困在 textarea 中。
回答by elgholm
For what it's worth, here's my oneliner, for what you all have been talking about in this thread:
对于它的价值,这是我的 oneliner,对于你们在这个线程中一直在谈论的内容:
<textarea onkeydown="if(event.keyCode===9){var v=this.value,s=this.selectionStart,e=this.selectionEnd;this.value=v.substring(0, s)+'\t'+v.substring(e);this.selectionStart=this.selectionEnd=s+1;return false;}">
</textarea>
Testest in latest editions of Chrome, Firefox, Internet Explorer and Edge.
在最新版本的 Chrome、Firefox、Internet Explorer 和 Edge 中进行测试。
回答by Yom S.
Modern way that both is straight-forward and does not lose the ability to undo(Ctrl+Z) the last changes.
现代方式既直接又不会失去撤消(Ctrl + Z)最后更改的能力。
$('#your-textarea').keydown(function (e) {
var keyCode = e.keyCode || e.which;
if (keyCode === $.ui.keyCode.TAB) {
e.preventDefault();
const TAB_SIZE = 4;
// The one-liner that does the magic
document.execCommand('insertText', false, ' '.repeat(TAB_SIZE));
}
});
More about execCommand
:
更多关于execCommand
:
Edit:
编辑:
As pointed out in the comment (and while this was once a "modern" solution), the feature has gone obsolete. Quoting the docs:
正如评论中所指出的(虽然这曾经是一个“现代”解决方案),但该功能已经过时了。引用文档:
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.
此功能已过时。尽管它可能在某些浏览器中仍然有效,但不鼓励使用它,因为它可以随时被删除。尽量避免使用它。
回答by Brad Robinson
Here's my version of this, supports:
这是我的版本,支持:
- tab + shift tab
- maintains undo stack for simple tab character inserts
- supports block line indent/unindent but trashes undo stack
- properly selects whole lines when block indent/unindent
- supports auto indent on pressing enter (maintains undo stack)
- use Escape key cancel support on next tab/enter key (so you can press Escape then tab out)
- Works on Chrome + Edge, untested others.
- 制表符 + 移位制表符
- 为简单的制表符插入维护撤消堆栈
- 支持块行缩进/取消缩进,但会破坏撤消堆栈
- 块缩进/取消缩进时正确选择整行
- 支持按下回车时自动缩进(维护撤消堆栈)
- 在下一个选项卡/输入键上使用 Escape 键取消支持(因此您可以按 Escape 然后退出)
- 适用于 Chrome + Edge,其他未经测试。
$(function() {
var enabled = true;
$("textarea.tabSupport").keydown(function(e) {
// Escape key toggles tab on/off
if (e.keyCode==27)
{
enabled = !enabled;
return false;
}
// Enter Key?
if (e.keyCode === 13 && enabled)
{
// selection?
if (this.selectionStart == this.selectionEnd)
{
// find start of the current line
var sel = this.selectionStart;
var text = $(this).val();
while (sel > 0 && text[sel-1] != '\n')
sel--;
var lineStart = sel;
while (text[sel] == ' ' || text[sel]=='\t')
sel++;
if (sel > lineStart)
{
// Insert carriage return and indented text
document.execCommand('insertText', false, "\n" + text.substr(lineStart, sel-lineStart));
// Scroll caret visible
this.blur();
this.focus();
return false;
}
}
}
// Tab key?
if(e.keyCode === 9 && enabled)
{
// selection?
if (this.selectionStart == this.selectionEnd)
{
// These single character operations are undoable
if (!e.shiftKey)
{
document.execCommand('insertText', false, "\t");
}
else
{
var text = this.value;
if (this.selectionStart > 0 && text[this.selectionStart-1]=='\t')
{
document.execCommand('delete');
}
}
}
else
{
// Block indent/unindent trashes undo stack.
// Select whole lines
var selStart = this.selectionStart;
var selEnd = this.selectionEnd;
var text = $(this).val();
while (selStart > 0 && text[selStart-1] != '\n')
selStart--;
while (selEnd > 0 && text[selEnd-1]!='\n' && selEnd < text.length)
selEnd++;
// Get selected text
var lines = text.substr(selStart, selEnd - selStart).split('\n');
// Insert tabs
for (var i=0; i<lines.length; i++)
{
// Don't indent last line if cursor at start of line
if (i==lines.length-1 && lines[i].length==0)
continue;
// Tab or Shift+Tab?
if (e.shiftKey)
{
if (lines[i].startsWith('\t'))
lines[i] = lines[i].substr(1);
else if (lines[i].startsWith(" "))
lines[i] = lines[i].substr(4);
}
else
lines[i] = "\t" + lines[i];
}
lines = lines.join('\n');
// Update the text area
this.value = text.substr(0, selStart) + lines + text.substr(selEnd);
this.selectionStart = selStart;
this.selectionEnd = selStart + lines.length;
}
return false;
}
enabled = true;
return true;
});
});
textarea
{
width: 100%;
height: 100px;
tab-size: 4;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea class="tabSupport">if (something)
{
// This textarea has "tabSupport" CSS style
// Try using tab key
// Try selecting multiple lines and using tab and shift+tab
// Try pressing enter at end of this line for auto indent
// Use Escape key to toggle tab support on/off
// eg: press Escape then Tab to go to next field
}
</textarea>
<textarea>This text area doesn't have tabSupport class so disabled here</textarea>
回答by stovroz
I was getting nowhere fast trying to use @kasdega's answer in an AngularJS environment, nothing I tried seemed able to make Angular act on the change. So in case it's of any use to passers by, here's a rewrite of @kasdega's code, AngularJS style, which worked for me:
在 AngularJS 环境中尝试使用 @kasdega 的答案时,我无处可去,我尝试过的任何东西似乎都无法让 Angular 对变化采取行动。因此,如果它对路人有用,这里是@kasdega 代码的重写,AngularJS 风格,它对我有用:
app.directive('ngAllowTab', function () {
return function (scope, element, attrs) {
element.bind('keydown', function (event) {
if (event.which == 9) {
event.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
element.val(element.val().substring(0, start)
+ '\t' + element.val().substring(end));
this.selectionStart = this.selectionEnd = start + 1;
element.triggerHandler('change');
}
});
};
});
and:
和:
<textarea ng-model="mytext" ng-allow-tab></textarea>
回答by mpen
This solution allows tabbing in an entire selection like your typical code editor, and untabbing that selection too. However, I haven't figured out how to implement shift-tab when there's no selection.
此解决方案允许像典型的代码编辑器一样在整个选择中使用 Tab,也可以取消该选择。但是,我还没有弄清楚如何在没有选择的情况下实现 shift-tab。
$('#txtInput').on('keydown', function(ev) {
var keyCode = ev.keyCode || ev.which;
if (keyCode == 9) {
ev.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
var val = this.value;
var selected = val.substring(start, end);
var re, count;
if(ev.shiftKey) {
re = /^\t/gm;
count = -selected.match(re).length;
this.value = val.substring(0, start) + selected.replace(re, '') + val.substring(end);
// todo: add support for shift-tabbing without a selection
} else {
re = /^/gm;
count = selected.match(re).length;
this.value = val.substring(0, start) + selected.replace(re, '\t') + val.substring(end);
}
if(start === end) {
this.selectionStart = end + count;
} else {
this.selectionStart = start;
}
this.selectionEnd = end + count;
}
});
#txtInput {
font-family: monospace;
width: 100%;
box-sizing: border-box;
height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="txtInput">
$(document).ready(function(){
$("#msgid").html("This is Hello World by JQuery");
});
</textarea>
回答by Aziz Shaikh
You have to write JS code to catch TAB key press and insert a bunch of spaces. Something similar to what JSFiddle does.
你必须编写 JS 代码来捕捉 TAB 键按下并插入一堆空格。类似于 JSFiddle 所做的事情。
Check jquery fiddle:
检查 jquery小提琴:
HTML:
HTML:
<textarea id="mybox">this is a test</textarea>
JavaScript:
JavaScript:
$('#mybox').live('keydown', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
alert('tab pressed');
}
});
?
回答by Martin
Multiple-line indetation script based on @kasdega solution.
基于@kasdega 解决方案的多行插入脚本。
$('textarea').on('keydown', function (e) {
var keyCode = e.keyCode || e.which;
if (keyCode === 9) {
e.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
var val = this.value;
var selected = val.substring(start, end);
var re = /^/gm;
var count = selected.match(re).length;
this.value = val.substring(0, start) + selected.replace(re, '\t') + val.substring(end);
this.selectionStart = start;
this.selectionEnd = end + count;
}
});