ใช้แท็บเพื่อเยื้องใน textarea


143

ฉันมี textarea HTML ง่าย ๆ อยู่ข้างๆ ตอนนี้ถ้าคุณคลิกที่แท็บมันจะไปที่ฟิลด์ถัดไป ฉันต้องการทำให้ปุ่มแท็บเยื้องช่องว่างเล็กน้อยแทน ฉันจะทำสิ่งนี้ได้อย่างไร ขอบคุณ


สิ่งนี้สามารถใช้กับ JavaScript ได้และเกือบจะใช้ไลบรารี JS ได้ง่าย คุณสามารถใช้ตัวเลือกเหล่านั้นได้หรือไม่?
เดวิดบอกว่าคืนสถานะโมนิก้า

สภาพแวดล้อมของคุณคืออะไร Javascript, Jquery, มีอย่างอื่นอีกไหม?
kasdega

@david ฉันสามารถใช้มันกับผู้ใช้คนใดก็ได้
user780483

ฉันจะใช้ jquery ร่วมกับการรวม. โฟกัส () และ. keydown ()
kasdega

8
เป็นไปได้ที่ซ้ำกันของวิธีการจัดการ <tab> ใน textarea?
Caspar Kleijne

คำตอบ:


121

ยืมมาจากคำตอบอื่น ๆ สำหรับคำถามที่คล้ายกัน (โพสต์ด้านล่าง) ...

$(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: วิธีจับปุ่มกด TAB ภายในกล่องข้อความ

วิธีจัดการ <tab> ใน textarea

http://jsfiddle.net/jz6J5/


13
"$ (นี้) รับการตอบสนอง (0) .selectionStart" ใช้เพียงแค่ "this.selectionStart"
Bohdan Yurov

คุณสามารถใช้มันเพื่อทำงานกับ 4 ช่องว่างแทน \ t? หากคุณแทนที่ \ t ด้วย "" จะเป็นการแทรกช่องว่าง แต่ทิ้งเครื่องหมายรูปหมวกไว้
Sinaesthetic

@Sinaesthetic - การตอบกลับล่าช้า แต่เมื่อต้องการย้ายเครื่องหมายรูปหมวกให้ปรับบรรทัดสุดท้ายเป็น 'start + 4' แทน 'start + 1'
nevada_scout

4
ฉันมักจะไม่คัดลอกรหัสโดยตรงจาก Stackoverflow และวางลงในโครงการของฉันและใช้งานได้ แต่เมื่อฉันทำมันเป็นรหัสนี้ ขอบคุณสำหรับสิ่งนี้.
Flat Cat

10
สิ่งนี้จะทำลายคุณลักษณะการเลิกทำของเบราว์เซอร์ (Ctrl + z)
01AutoMonkey

54
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 และจะเปิดใช้งานฟังก์ชั่นแท็บใน textareas ทั้งหมดในหน้า


คุณสามารถใช้มันเพื่อทำงานกับ 4 ช่องว่างแทน \ t? หากคุณแทนที่ \ t ด้วย "" จะเป็นการแทรกช่องว่าง แต่ทิ้งเครื่องหมายรูปหมวกไว้
Sinaesthetic

1
@Sinaesthetic: ใช่คุณอาจเปลี่ยนแท็บเป็นช่องว่าง แต่คุณต้องปรับเปลี่ยนรหัสเล็กน้อย (มีตัวอักษรใหม่ 3-4 ตัวแทนที่จะเป็นหนึ่งตัว) อีกทางเลือกหนึ่งคือขนาดแท็บ CSS
Adrian Maire

@Sinaesthetic ใช่เพียงแทนที่บรรทัดสุดท้ายด้วยthis.selectionEnd = s+1; this.selectionEnd = s + "\t".length;มันจะสะอาดกว่าถ้าใช้ตัวแปรหรือฟังก์ชั่นพารามิเตอร์และเก็บการเว้นวรรคไว้ที่นั่น แต่คุณรู้ว่าต้องเปลี่ยนอะไรในตอนนี้: การ+1กำหนดจำนวนตัวอักษรที่ถูกย้ายเครื่องหมายรูปหมวก
StanE

2
KeyboardEvent.keyCodeและKeyboardEvent.whichเป็นคุณสมบัติที่เลิกใช้แล้ว ใช้KeyboardEvent.keyแทน
КонстантинВан

48

ตามที่คนอื่นเขียนคุณสามารถใช้ JavaScript เพื่อบันทึกเหตุการณ์ป้องกันการกระทำเริ่มต้น (เพื่อให้เคอร์เซอร์ไม่เปลี่ยนโฟกัส) และแทรกอักขระแท็บ

แต่การปิดใช้งานพฤติกรรมเริ่มต้นทำให้ไม่สามารถย้ายโฟกัสออกจากพื้นที่ข้อความโดยไม่ต้องใช้เมาส์ ผู้ใช้ที่ตาบอดสามารถโต้ตอบกับเว็บเพจโดยใช้แป้นพิมพ์และไม่มีอะไรอื่น - พวกเขาไม่สามารถเห็นตัวชี้เมาส์เพื่อทำสิ่งที่มีประโยชน์กับมันดังนั้นจึงเป็นคีย์บอร์ดหรืออะไรก็ได้ ปุ่มแท็บเป็นวิธีหลักในการสำรวจเอกสารและโดยเฉพาะอย่างยิ่งรูปแบบ การเอาชนะพฤติกรรมเริ่มต้นของคีย์แท็บจะทำให้ผู้ใช้ที่ตาบอดไม่สามารถย้ายโฟกัสไปยังองค์ประกอบของฟอร์มถัดไป

ดังนั้นหากคุณเขียนเว็บไซต์สำหรับกลุ่มเป้าหมายกว้าง ๆ ฉันขอแนะนำให้ทำเช่นนี้โดยไม่มีเหตุผลที่น่าสนใจและเสนอทางเลือกบางอย่างสำหรับผู้ใช้ที่ตาบอดซึ่งไม่ได้ดักจับพวกเขาใน textarea


2
ขอบคุณ. ฉันไม่ได้ตั้งใจฟังเสียงหยาบคาย แต่ฉันไม่รู้ว่าคนตาบอดใช้คอมพิวเตอร์ ฉันจะจำสิ่งนี้ไว้
user780483

10
ไม่เป็นไรผู้คนมากมายไม่รู้ มันอยู่นอกประสบการณ์ของพวกเขา นี่คือคำแนะนำ: webaim.org/intro
Will Martin

ใช่ความคิดที่ดีจริงๆถ้านี่เป็นเว็บไซต์สำหรับผู้ชมทั่วไป นอกเหนือจากผู้ใช้โปรแกรมอ่านหน้าจอแล้วยังมีผู้ใช้อื่น ๆ อีกมากมายที่ต้องการหรือนำทางด้วยคีย์บอร์ดด้วยเหตุผลต่าง ๆ การวางคีย์แท็บจะทำให้ฟอร์มน่ารำคาญอย่างน้อยและอาจไม่สามารถใช้ได้สำหรับผู้ใช้เหล่านี้
steveax

6
อาจใช้แท็บควบคุม + สิ่งนี้จะช่วยเพิ่มความสามารถของเบราว์เซอร์ให้กับแท็บอื่น ๆ (หน้าเว็บ) แต่ผู้ใช้สามารถแท็บออกจากกล่องข้อความจากนั้นควบคุมแท็บไปยังหน้าอื่น ๆ ควรมีคำใบ้บนหน้าใช้ ctrl + แท็บสำหรับแท็บ
Joseph McIntyre

ขอบคุณ @WillMartin ข้อมูลที่มีค่ามาก ๆ ฉันจะใช้สิ่งเดียวกันในบล็อกทั้งหมดของฉันสำหรับ textarea ทั้งหมดโดยไม่คำนึงถึงประเด็นที่สำคัญมากนี้
Imran

40

สำหรับสิ่งที่คุ้มค่านี่คือ 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 รุ่นล่าสุด


คุณเป็นคนที่ยอดเยี่ยมมาก
NiCk Newman

1
ฉันจะแก้ไขรหัสนี้เพื่อใช้ช่องว่าง 4 แทนที่จะเป็นแท็บได้อย่างไร ฉันพยายามทำ & nbsp; สี่ครั้ง แต่ยังคงแปลงเป็นพื้นที่เดียว
jiaweizhang

5
โปรดบอกภรรยาของฉัน jiaweizhang แทนที่ '\ t' ด้วย '<4 ช่องว่าง>' และ 1 ด้วย 4.
elgholm

1
คำตอบที่ดีที่สุด!
Marco Demaio

1
เรียบร้อยมากนี่คือสิ่งที่ตรงกันข้ามผ่าน 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;}}
DonFuchs

12

นี่คือเวอร์ชั่นของฉันที่รองรับ:

  • tab + shift tab
  • เก็บเลิกทำกองซ้อนสำหรับการแทรกตัวอักษรแท็บอย่างง่าย
  • สนับสนุนการบล็อกบรรทัดเยื้อง / unindent แต่ทับซ้อนเลิกทำกองซ้อน
  • เลือกทั้งบรรทัดอย่างถูกต้องเมื่อบล็อกการเยื้อง / การรวม
  • รองรับการเยื้องอัตโนมัติเมื่อกด Enter (รักษาการยกเลิกเลิกซ้อน)
  • ใช้คีย์ 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>


1
นี่คือคำตอบที่ดีที่สุดที่นี่
FourCinnamon0

สิ่งนี้ทำงานได้โดยไม่ต้อง jQuery ด้วยการทำงานเล็กน้อย ตรวจสอบ youmightnotneedjquery.com เพื่อรับความช่วยเหลือ คำตอบที่ดีที่สุดแน่นอนที่นี่เช่นกัน
Jamon Holmgren

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));
    }
});

เพิ่มเติมเกี่ยวกับexecCommand:


แก้ไข:

ตามที่ระบุไว้ในความคิดเห็น (และในขณะนี้เคยเป็นโซลูชัน "ทันสมัย" ) คุณลักษณะดังกล่าวล้าสมัยไปแล้ว การอ้างอิงเอกสาร:

คุณลักษณะนี้ล้าสมัย แม้ว่ามันอาจจะยังคงใช้งานได้ในบางเบราว์เซอร์ แต่การใช้งานนั้นไม่ได้รับการสนับสนุนเนื่องจากสามารถลบออกได้ตลอดเวลา พยายามหลีกเลี่ยงการใช้งาน


3
นี่เป็นคำตอบเดียวที่ถูกต้อง ณ จุดนี้ ขอบคุณมาก 🙏
Chris Calo

2
น่าเศร้าที่ไม่รองรับ Firefox ลองindent-textareaวิธีแก้ปัญหาข้ามเบราว์เซอร์ที่ใช้วิธีนี้ + ทางเลือกใน Firefox
Fregante

ใน Firefox document.execCommandจะเปิดใช้งานหลังจากการตั้งค่าdocument.designMode = "on";เท่านั้น .contentEditable = 'true'ฉันสามารถที่จะได้รับข้อความที่จะเขียนเป็นองค์ประกอบที่มี อย่างไรก็ตามเมื่อฉันพยายามทำสิ่งนี้ให้สำเร็จบน textarea textNode ที่แทรกไว้จะถูกวางไว้ด้านหน้า textarea ภายในเอกสาร (แทนที่จะเป็น textarea) กรุณาพยายามที่จะช่วยให้รูป Mozilla นี้ออกจากที่นี่
Lonnie Best

โปรดทราบว่านี่จะไม่ถือว่าเป็น 'ทันสมัย' หน้าเว็บที่คุณเชื่อมโยงโน้ต (ประมาณexecCommand): 'ฟีเจอร์นี้ล้าสมัยแล้ว แม้ว่ามันอาจจะยังคงใช้งานได้ในบางเบราว์เซอร์ แต่การใช้งานนั้นไม่ได้รับการสนับสนุนเนื่องจากสามารถลบออกได้ตลอดเวลา พยายามหลีกเลี่ยงการใช้งาน '
kasimir

9

ฉันพยายามอย่างรวดเร็วเพื่อใช้คำตอบของ @ kasdega ในสภาพแวดล้อมของ AngularJS ไม่มีอะไรที่ฉันพยายามจะทำให้ Angular ดำเนินการเปลี่ยนแปลงได้ ดังนั้นในกรณีที่ผู้ใช้งานผ่านไปมาได้โปรดเขียนโค้ดของ @ kasdega, AngularJS style ซึ่งใช้งานได้สำหรับฉัน:

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');
            }
        });
    };
});

และ:

<textarea ng-model="mytext" ng-allow-tab></textarea>

มันสำคัญมากที่จะต้องโทรelement.triggerHandler('change');มิฉะนั้นโมเดลจะไม่ได้รับการอัปเดต (เพราะelement.triggerHandler('change');ฉันคิดว่า
Alvaro Flaño Larrondo

6

คุณต้องเขียนโค้ด JS เพื่อกดปุ่ม TAB และใส่ที่ว่าง สิ่งที่คล้ายกับสิ่งที่ JSFiddle ทำ

ตรวจสอบซอ jquery :

HTML :

<textarea id="mybox">this is a test</textarea>

จาวาสคริปต์ :

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

  if (keyCode == 9) { 
    e.preventDefault(); 
    alert('tab pressed');
  } 
});

2
อย่าลืมที่จะป้องกันการกระทำเริ่มต้นเช่นกัน event.preventDefault();
Ryan

2
Live ได้ถูกแทนที่ด้วยในรุ่นที่ใหม่กว่า
Eric Harms

คุณสมบัติ event.which normalizes event.keyCode และ event.charCode e.keyCode || e.whichคุณไม่ควรจะต้องตรวจสอบ
เทรเวอร์

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;
    }
});

1
ทางออกที่ดีที่สุดเพื่อให้ห่างไกล start === endแต่มันอาจจะไม่ได้สร้างตัวเลือกเมื่อ
mpen

6

โซลูชันนี้ช่วยให้การแท็บในตัวเลือกทั้งหมดเช่นโปรแกรมแก้ไขรหัสทั่วไปของคุณและไม่ทำการแท็บส่วนที่เลือกด้วย อย่างไรก็ตามฉันไม่ได้หาวิธีใช้แท็บการเลื่อนเมื่อไม่มีตัวเลือก

$('#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>


วิธีนี้ใช้งานได้ดี แต่อย่างน้อยคุณก็สามารถ จำกัด แท็บการเลื่อนโดยไม่มีการเลือกจากการโยนข้อผิดพลาด ฉันทำมันด้วยif (selected.length > 0) {...}Fiddle ง่ายๆ: jsfiddle.net/jwfkbjkr

3

ขึ้นอยู่กับสิ่งที่ผู้คนต้องพูดที่นี่กับคำตอบมันเป็นเพียงการรวมกันของ keydown (ไม่ใช่ keyup) + preventDefault () + แทรกอักขระแท็บที่เครื่องหมายรูปหมวก สิ่งที่ต้องการ:

var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
   e.preventDefault();
   insertAtCaret('txt', '\t')
}

คำตอบก่อนหน้านี้มี jsfiddle ที่ใช้งานได้ แต่ใช้การแจ้งเตือน () กับการเลื่อนลง หากคุณลบการแจ้งเตือนนี้แสดงว่าไม่ได้ทำงาน ฉันเพิ่งเพิ่มฟังก์ชั่นเพื่อแทรกแท็บที่ตำแหน่งเคอร์เซอร์ปัจจุบันใน textarea

นี่คือการทำงาน jsfiddle สำหรับสิ่งเดียวกัน: http://jsfiddle.net/nsHGZ/


3

ฉันเห็นหัวข้อนี้ไม่ได้รับการแก้ไข ฉันเขียนโค้ดนี้และมันทำงานได้ดีมาก มันแทรกตารางที่ดัชนีเคอร์เซอร์ โดยไม่ต้องใช้ jquery

<textarea id="myArea"></textarea>
<script>
document.getElementById("myArea").addEventListener("keydown",function(event){
    if(event.code==="Tab"){
        var cIndex=this.selectionStart;
        this.value=[this.value.slice(0,cIndex),//Slice at cursor index
            "\t",                              //Add Tab
            this.value.slice(cIndex)].join('');//Join with the end
        event.stopPropagation();
        event.preventDefault();                //Don't quit the area
        this.selectionStart=cIndex+1;
        this.selectionEnd=cIndex+1;            //Keep the cursor in the right index
    }
});
</script>

2
รหัสนี้จะทำให้กองการเลิกทำยุ่ง หลังการใช้งานแทรกแท็บบางครั้งคุณไม่สามารถเลิกทำอะไรเลยหรือย้อนกลับไปเพียง 1-2 ขั้นตอน
แมกนัส Eriksson


2

ฉันทำสิ่งที่คุณสามารถเข้าถึงได้ด้วยองค์ประกอบ textarea ใด ๆ ที่คุณต้องการ:

function textControl (element, event)
{
    if(event.keyCode==9 || event.which==9)
    {
        event.preventDefault();
        var s = element.selectionStart;
        element.value = element.value.substring(0,element.selectionStart) + "\t" + element.value.substring(element.selectionEnd);
        element.selectionEnd = s+1; 
    }
}

และองค์ประกอบจะมีลักษณะเช่นนี้:

<textarea onkeydown="textControl(this,event)"></textarea>

2

วิธีที่ง่ายที่สุดที่ผมพบว่าจะทำอย่างนั้นในเบราว์เซอร์ที่ทันสมัยกับวานิลลา JavaScriptคือ:

  <textarea name="codebox"></textarea>
  
  <script>
  const codebox = document.querySelector("[name=codebox]")

  codebox.addEventListener("keydown", (e) => {
    let { keyCode } = e;
    let { value, selectionStart, selectionEnd } = codebox;

    if (keyCode === 9) {  // TAB = 9
      e.preventDefault();

      codebox.value = value.slice(0, selectionStart) + "\t" + value.slice(selectionEnd);

      codebox.setSelectionRange(selectionStart+2, selectionStart+2)
    }
  });
  </script>

โปรดทราบว่าฉันใช้คุณสมบัติ ES6 มากมายในตัวอย่างนี้เพื่อความเรียบง่ายคุณอาจต้องการ transpile (ด้วย Babel หรือ TypeScript) ก่อนที่จะนำไปใช้งาน


1

คำตอบข้างต้นทั้งหมดล้างประวัติเลิกทำ สำหรับทุกคนที่กำลังมองหาโซลูชันที่ไม่ทำอย่างนั้นฉันใช้เวลาเขียนโค้ดชั่วโมงต่อไปนี้สำหรับ Chrome:

jQuery.fn.enableTabs = function(TAB_TEXT){
    // options
    if(!TAB_TEXT)TAB_TEXT = '\t';
    // text input event for character insertion
    function insertText(el, text){
        var te = document.createEvent('TextEvent');
        te.initTextEvent('textInput', true, true, null, text, 9, "en-US");
        el.dispatchEvent(te);
    }
    // catch tab and filter selection
    jQuery(this).keydown(function(e){
        if((e.which || e.keyCode)!=9)return true;
        e.preventDefault();
        var contents = this.value,
            sel_start = this.selectionStart,
            sel_end = this.selectionEnd,
            sel_contents_before = contents.substring(0, sel_start),
            first_line_start_search = sel_contents_before.lastIndexOf('\n'),
            first_line_start = first_line_start_search==-1 ? 0 : first_line_start_search+1,
            tab_sel_contents = contents.substring(first_line_start, sel_end),
            tab_sel_contents_find = (e.shiftKey?new RegExp('\n'+TAB_TEXT, 'g'):new RegExp('\n', 'g')),
            tab_sel_contents_replace = (e.shiftKey?'\n':'\n'+TAB_TEXT);
            tab_sel_contents_replaced = (('\n'+tab_sel_contents)
                .replace(tab_sel_contents_find, tab_sel_contents_replace))
                .substring(1),
            sel_end_new = first_line_start+tab_sel_contents_replaced.length;
        this.setSelectionRange(first_line_start, sel_end);
        insertText(this, tab_sel_contents_replaced);
        this.setSelectionRange(first_line_start, sel_end_new);
    });
};

ในระยะสั้นแท็บจะถูกแทรกที่จุดเริ่มต้นของบรรทัดที่เลือก

JSFiddle: http://jsfiddle.net/iausallc/5Lnabspr/11/

สรุป: https://gist.github.com/iautomation/e53647be326cb7d7112d

ตัวอย่างการใช้งาน: $('textarea').enableTabs('\t')

ข้อด้อย: ใช้งานได้กับ Chrome ตามที่เป็นอยู่เท่านั้น


ส่วนใดของสคริปต์นี้ใช้งานได้เฉพาะใน Chrome มันคือ "TextEvent" หรือไม่? help.dottoro.com/lagstsiq.php/#TextEventไซต์นี้ระบุว่าควรทำงานใน IE9 + และ Safari เนื่องจากฉันต้องการสิ่งนี้สำหรับแอป Chrome นี่จึงสมบูรณ์แบบ
Andreas Linnert

@ Andreas Linnert คุณพูดถูก มีการบันทึกไว้เพื่อทำงานทั้งใน IE และ Safari อย่างไรก็ตามในขณะที่เขียนนี้ IE ไม่ทำงานสำหรับฉันและฉันก็ไม่มีเวลาที่จะตรวจสอบเพิ่มเติมและฉันไม่ได้ทดสอบใน Safari ขออภัยในความสับสน ฉันดีใจที่ได้ช่วย
iautomation

0

มีห้องสมุดบน Github สำหรับการสนับสนุนแท็บใน textareas ของคุณโดย wjbryant: Tab Override

นี่คือวิธีการทำงาน:

// get all the textarea elements on the page
var textareas = document.getElementsByTagName('textarea');

// enable Tab Override for all textareas
tabOverride.set(textareas);

ไม่ได้คำตอบที่ไม่ดี แต่มองไปที่รหัสจะใช้เทคนิคสวยมากเช่นเดียวกับคนที่อธิบายไว้ในบางส่วนของคำตอบที่นี่: github.com/wjbryant/taboverride/blob/master/src/... ซึ่งหมายความว่าจะไม่รักษาประวัติการเลิกทำซึ่งเป็นปัญหาหลัก
mihai

0

ในฐานะที่เป็นตัวเลือกสำหรับรหัสของ kasdega ด้านบนแทนที่จะเพิ่มแท็บต่อท้ายกับค่าปัจจุบันคุณสามารถแทรกอักขระที่จุดเคอร์เซอร์ปัจจุบันแทน นี่คือประโยชน์ของ:

  • อนุญาตให้คุณแทรกช่องว่าง 4 อันแทนแท็บ
  • การเลิกทำและทำซ้ำจะใช้งานได้กับอักขระที่แทรก (จะไม่ใช้ OP)

ดังนั้นแทนที่

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

กับ

    // set textarea value to: text before caret + tab + text after caret
    document.execCommand("insertText", false, '    ');

-1
if (e.which == 9) {
    e.preventDefault();
    var start = $(this).get(0).selectionStart;
    var end = $(this).get(0).selectionEnd;

    if (start === end) {
        $(this).val($(this).val().substring(0, start)
                    + "\t"
                    + $(this).val().substring(end));
        $(this).get(0).selectionStart =
        $(this).get(0).selectionEnd = start + 1;
    } else {
        var sel = $(this).val().substring(start, end),
            find = /\n/g,
            count = sel.match(find) ? sel.match(find).length : 0;
        $(this).val($(this).val().substring(0, start)
                    + "\t"
                    + sel.replace(find, "\n\t")
                    + $(this).val().substring(end, $(this).val().length));
        $(this).get(0).selectionStart =
        $(this).get(0).selectionEnd = end+count+1;
    }
}

-1

ลองใช้ฟังก์ชั่น jQuery ง่ายๆนี้:

$.fn.getTab = function () {
    this.keydown(function (e) {
        if (e.keyCode === 9) {
            var val = this.value,
                start = this.selectionStart,
                end = this.selectionEnd;
            this.value = val.substring(0, start) + '\t' + val.substring(end);
            this.selectionStart = this.selectionEnd = start + 1;
            return false;
        }
        return true;
    });
    return this;
};

$("textarea").getTab();
// You can also use $("input").getTab();

-1

ฉันต้องทำให้ฟังก์ชั่นทำเช่นเดียวกันมันใช้ง่ายเพียงแค่คัดลอกโค้ดนี้ไปยังสคริปต์ของคุณและใช้: enableTab( HTMLElement )HTMLelement เป็นสิ่งที่ชอบdocument.getElementById( id )


รหัสคือ:

function enableTab(t){t.onkeydown=function(t){if(9===t.keyCode){var e=this.value,n=this.selectionStart,i=this.selectionEnd;return this.value=e.substring(0,n)+" "+e.substring(i),this.selectionStart=this.selectionEnd=n+1,!1}}}

-1

ทุกการป้อนองค์ประกอบ textarea มีเหตุการณ์ onkeydown ในตัวจัดการเหตุการณ์คุณสามารถป้องกันปฏิกิริยาเริ่มต้นของแท็บคีย์โดยใช้event.preventDefault ()เมื่อใดก็ตามที่ event.keyCode คือ 9

จากนั้นให้ใส่แท็บในตำแหน่งที่ถูกต้อง:

function allowTab(input)
{
    input.addEventListener("keydown", function(event)
    {
        if(event.keyCode == 9)
        {
            event.preventDefault();

            var input = event.target;

            var str = input.value;
            var _selectionStart = input.selectionStart;
            var _selectionEnd = input.selectionEnd;

            str = str.substring(0, _selectionStart) + "\t" + str.substring(_selectionEnd, str.length);
            _selectionStart++;

            input.value = str;
            input.selectionStart = _selectionStart;
            input.selectionEnd = _selectionStart;
        }
    });
}

window.addEventListener("load", function(event)
{
    allowTab(document.querySelector("textarea"));
});

HTML

<textarea></textarea>

-1
$("textarea").keydown(function(event) {
    if(event.which===9){
        var cIndex=this.selectionStart;
        this.value=[this.value.slice(0,cIndex),//Slice at cursor index
            "\t",                              //Add Tab
            this.value.slice(cIndex)].join('');//Join with the end
        event.stopPropagation();
        event.preventDefault();                //Don't quit the area
        this.selectionStart=cIndex+1;
        this.selectionEnd=cIndex+1;            //Keep the cursor in the right index
    }
});

-1

สคริปต์แบบสแตนด์อโลนอย่างง่าย:

textarea_enable_tab_indent = function(textarea) {    
    textarea.onkeydown = function(e) {
        if (e.keyCode == 9 || e.which == 9){
            e.preventDefault();
            var oldStart = this.selectionStart;
            var before   = this.value.substring(0, this.selectionStart);
            var selected = this.value.substring(this.selectionStart, this.selectionEnd);
            var after    = this.value.substring(this.selectionEnd);
            this.value = before + "    " + selected + after;
            this.selectionEnd = oldStart + 4;
        }
    }
}

-3

หากคุณต้องการแท็บให้คัดลอกแท็บจากคำหรือแผ่นจดบันทึกแล้ววางลงในกล่องข้อความที่คุณต้องการ

1 2 3

12 22 33

น่าเสียดายที่ฉันคิดว่าพวกเขาลบแท็บออกจากความคิดเห็นเหล่านี้ :) มันจะแสดงเป็น% 09 ใน POST หรือ GET ของคุณ


2
ฉันคิดว่านี่เป็นคำตอบ แต่ก็เป็นคำตอบที่แย่จริงๆ มันแนะนำวิธีการทางเลือกคือให้วิธีการแก้ปัญหาแก่ผู้ใช้ปลายทาง
GS - ขอโทษ Monica เมื่อ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.