使用制表符在 textarea 中缩进

IT技术 javascript html textarea
2021-01-14 05:12:59

我的网站上有一个简单的 HTML 文本区域。

现在,如果您单击Tab它,它会转到下一个字段。我想让标签按钮缩进几个空格。

我怎样才能做到这一点?

6个回答

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

document.getElementById('textbox').addEventListener('keydown', function(e) {
  if (e.key == 'Tab') {
    e.preventDefault();
    var start = this.selectionStart;
    var end = this.selectionEnd;

    // set textarea value to: text before caret + tab + text after caret
    this.value = this.value.substring(0, start) +
      "\t" + this.value.substring(end);

    // put caret at right position again
    this.selectionStart =
      this.selectionEnd = start + 1;
  }
});
<input type="text" name="test1" />
<textarea id="textbox" name="test2"></textarea>
<input type="text" name="test3" />

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

如何处理textarea中的<tab>?

“$(this).get(0).selectionStart”。只使用“this.selectionStart”
2021-03-15 05:12:59
@Sinaesthetic - 回复晚,但要移动插入符号,请将最后一行调整为“start + 4”而不是“start + 1”
2021-03-16 05:12:59
你能用 4 个空格代替 \t 吗?如果将 \t 替换为“”,它将插入空格但将插入符号留在后面。
2021-03-18 05:12:59
我通常不会直接从 Stackoverflow 复制代码并将其粘贴到我的项目中并使其工作,但是当我这样做时,就是这段代码。谢谢你。
2021-03-21 05:12:59
这会破坏浏览器的撤消功能 (Ctrl+z)。
2021-04-06 05:12:59
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; 
        }
    }
}

此解决方案不需要 jQuery,并且将在页面上的所有文本区域上启用选项卡功能。

你能用 4 个空格代替 \t 吗?如果将 \t 替换为“”,它将插入空格但将插入符号留在后面。
2021-03-19 05:12:59
@StanE - 我在制表符上使用了您的建议,现在单个制表符占据了大约 6 个空格字符的宽度,这正是我想要的 - 当您使用光标键浏览文本时,插入符号现在会跳过该制表符距离在一个单一的按键。该选项卡也用一个退格键删除。只是在这里注意其他任何想要制表符看起来也像制表符的人。
2021-03-21 05:12:59
@Sinaesthetic:是的,您可以将制表符更改为空格,但您必须稍微调整一下代码(有 3-4 个新字母而不是一个)。另一种选择是 CSS 标签大小。
2021-03-26 05:12:59
KeyboardEvent.keyCode并且KeyboardEvent.which是不推荐使用的属性。使用KeyboardEvent.key来代替。
2021-04-01 05:12:59
@Sinaesthetic 是的,只需将最后一行替换this.selectionEnd = s+1;this.selectionEnd = s + "\t".length;. 使用变量或函数参数并将缩进字符存储在那里会更干净。但是您现在知道要替换什么了:+1定义了插入符号移动了多少个字符。
2021-04-09 05:12:59

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

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

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

谢谢。我的意思不是说粗鲁,但我不知道盲人会使用电脑。我会牢记这一点
2021-03-25 05:12:59
是的,如果这是一个面向普通观众的网站,那真是个坏主意。除了屏幕阅读器用户之外,还有许多其他用户出于各种原因必须或选择使用键盘导航。捕获 Tab 键将使表单至少令人讨厌,并且很可能对这些用户无法使用。
2021-03-28 05:12:59
谢谢@WillMartin 非常有value的信息。我打算在我的整个博客中为所有 textarea 实现同样的事情,而不考虑这个非常关键的点。
2021-03-28 05:12:59
没关系,很多人不知道;这只是在他们的经验之外。这是一个介绍:webaim.org/intro
2021-04-06 05:12:59
也许使用控制+选项卡。这将劫持浏览器对其他选项卡(网页)的能力,但用户只需从文本框选项卡中退出,然后将选项卡控制到其他页面即可。页面上应该有提示,请使用 ctrl + tab for tab。
2021-04-13 05:12:59

对于它的value,这是我的 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>

在最新版本的 Chrome、Firefox、Internet Explorer 和 Edge 中进行测试。

最佳答案!
2021-03-16 05:12:59
如何修改此代码以使用 4 个空格而不是制表符?我试着做   四次,但它仍然将其转换为一个空格。
2021-03-17 05:12:59
非常整洁,这是通过 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;}}
2021-03-23 05:12:59
先生,你真了不起。
2021-03-24 05:12:59
尼克,请告诉我的妻子。jiaweizhang,将 '\t' 替换为 '<4 个空格>',将 1 替换为 4。
2021-04-07 05:12:59

这是我的版本,支持:

  • 制表符 + 移位制表符
  • 为简单的制表符插入维护撤消堆栈
  • 支持块行缩进/取消缩进,但会破坏撤消堆栈
  • 块缩进/取消缩进时正确选择整行
  • 支持按回车自动缩进(维护撤消堆栈)
  • 在下一个选项卡/输入键上使用 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>

这是这里最好的答案。
2021-03-28 05:12:59
我不知道为什么这不是公认的答案,它非常优雅。我需要在 TypeScript 类(没有 jQuerY)中使用它,所以我想我会分享我的类,因为它可以帮助其他人:jsfiddle.net/2wkrhxLt/8
2021-03-31 05:12:59
这在没有 jQuery 的情况下工作,只需一点点工作。检查youmightnotneedjquery.com 寻求帮助。绝对是这里最好的答案,也是。
2021-04-08 05:12:59
@JamonHolmgren 没有 JQuery 一切都可以工作:vanilla-js.com
2021-04-10 05:12:59