使用tab在textarea中缩进

use*_*483 136 html textarea

我有一个简单的html textarea.现在,如果单击其中的选项卡,它将转到下一个字段.我想让标签按钮缩进几个空格.我怎样才能做到这一点?谢谢.

kas*_*ega 115

从类似问题的其他答案中大量借用(下面发布)......

$(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;
  }
});
Run Code Online (Sandbox Code Playgroud)

jQuery:如何捕获文本框中的TAB按键

如何在textarea中处理<tab>?

http://jsfiddle.net/jz6J5/

  • "$(本)获得(0).selectionStart".只使用"this.selectionStart" (13认同)
  • 这会破坏浏览器的撤消功能(Ctrl + z). (8认同)
  • 我通常不直接从Stackoverflow复制代码并将其粘贴到我的项目中并让它工作,但是当我这样做时,就是这段代码.谢谢你. (3认同)

小智 52

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; 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

此解决方案不需要jQuery,并将在页面上的所有textareas上启用选项卡功能.

  • `KeyboardEvent.keyCode` 和 `KeyboardEvent.which` 是不推荐使用的属性。改用 [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)。 (3认同)

Wil*_*tin 40

正如其他人所写,您可以使用JavaScript捕获事件,防止默认操作(以便光标不会移动焦点)并插入制表符.

但是,禁用默认行为会导致无法使用鼠标将焦点移出文本区域.盲人用户使用键盘与网页互动,没有别的 - 他们看不到鼠标指针对它做任何有用的事情,所以它是键盘或什么也没有.Tab键是导航文档的主要方式,尤其是表单.覆盖tab键的默认行为将使盲人用户无法将焦点移动到下一个表单元素.

因此,如果您正在为广大受众撰写网站,我建议不要在没有令人信服的理由的情况下这样做,并为盲人用户提供某种替代方案,而不会将他们陷入textarea.

  • 没关系,很多人都不知道; 它只是在他们的经验之外.以下是介绍:http://webaim.org/intro/ (10认同)
  • 也许使用control + tab.这将使浏览器对其他选项卡(网页)的能力高,但用户只需从文本框中跳出选项卡,然后将选项卡控制到另一个页面.应该在页面上有一个提示使用ctrl + tab for tab. (5认同)
  • 谢谢.我不是说听起来不好,但我不知道盲人使用电脑.我会记住这一点 (2认同)

elg*_*olm 33

对于它的价值,这是我的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>
Run Code Online (Sandbox Code Playgroud)

Testest在Chrome,Firefox,Internet Explorer和Edge的最新版本中.

  • NiCk,请告诉我的妻子.jiaweizhang,将'\ t'替换为'<4 spaces>',将1替换为4. (3认同)
  • 最佳答案! (2认同)
  • 非常简洁,这是通过 SHIFT 实现的相反操作: `if(event.shiftKey){if(v.substring(s-1,s)==='\t'){this.value=v.substring(0,s -1)+v.substring(e);this.selectionStart=this.selectionEnd=s-1;}}` (2认同)

Yom*_* S. 10

现代的方式,两者都是直截了当的,并没有失去撤消(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));
    }
});
Run Code Online (Sandbox Code Playgroud)

更多关于execCommand:

  • 这是目前唯一正确的答案.非常感谢你. (2认同)
  • 遗憾的是没有 Firefox 支持。尝试 [`indent-textarea`](https://github.com/bfred-it/indent-textarea) 以获得使用此方法的跨浏览器解决方案 + Firefox 中的回退。 (2认同)

sto*_*roz 9

在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');
            }
        });
    };
});
Run Code Online (Sandbox Code Playgroud)

和:

<textarea ng-model="mytext" ng-allow-tab></textarea>
Run Code Online (Sandbox Code Playgroud)


Bra*_*son 7

这是我的版本,支持:

  • 标签+ Shift标签
  • 维护撤消堆栈,以便简单地插入制表符
  • 支持块行缩进/取消缩进,但会撤消撤消堆栈
  • 块缩进/缩进时正确选择整行
  • 支持按Enter时自动缩进(保持撤消堆栈)
  • 在下一个选项卡/输入键上使用退出键取消支持(因此您可以按退出键然后退出)
  • 适用于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;
	});
});
Run Code Online (Sandbox Code Playgroud)
textarea
{
  width: 100%;
  height: 100px;
  tab-size: 4;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 这是这里最好的答案。 (2认同)
  • @JamonHolmgren 一切都可以在没有 JQuery 的情况下工作:http://vanilla-js.com/ (2认同)
  • 我不知道为什么这不是公认的答案,它非常优雅。我需要在 TypeScript 类(没有 jQuerY)中使用它,所以我想我会分享我的类,因为它可能会帮助其他人:https://jsfiddle.net/2wkrhxLt/8/ (2认同)

Azi*_*ikh 6

你必须编写JS代码来捕获TAB键按下并插入一堆空格.与JSFiddle类似的东西.

检查jquery 小提琴:

HTML:

<textarea id="mybox">this is a test</textarea>
Run Code Online (Sandbox Code Playgroud)

JavaScript:

$('#mybox').live('keydown', function(e) { 
  var keyCode = e.keyCode || e.which; 

  if (keyCode == 9) { 
    e.preventDefault(); 
    alert('tab pressed');
  } 
});
?
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记也要阻止默认操作.`event.preventDefault();` (2认同)
  • 在较新的版本中,Live 已替换为 on。 (2认同)

小智 6

基于@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;
    }
});
Run Code Online (Sandbox Code Playgroud)


mpe*_*pen 6

这个解决方案允许像典型的代码编辑器一样在整个选择中进行制表,并且也可以取消选择.但是,当没有选择时,我还没有想出如何实现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;
    }
});
Run Code Online (Sandbox Code Playgroud)
#txtInput {
  font-family: monospace;
  width: 100%;
  box-sizing: border-box;
  height: 200px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)