Tôi có một văn bản html đơn giản về phía tôi. Ngay bây giờ nếu bạn nhấp vào tab trong đó, nó sẽ chuyển sang trường tiếp theo. Tôi muốn làm cho nút tab thụt vào một vài khoảng trống thay thế. Tôi có thể làm cái này như thế nào? Cảm ơn.
Tôi có một văn bản html đơn giản về phía tôi. Ngay bây giờ nếu bạn nhấp vào tab trong đó, nó sẽ chuyển sang trường tiếp theo. Tôi muốn làm cho nút tab thụt vào một vài khoảng trống thay thế. Tôi có thể làm cái này như thế nào? Cảm ơn.
Câu trả lời:
Mượn nhiều từ các câu trả lời khác cho các câu hỏi tương tự (được đăng dưới đây) ...
$(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: Cách chụp phím TAB trong Hộp văn bản
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;
}
}
}
Giải pháp này không yêu cầu jQuery và sẽ kích hoạt chức năng tab trên tất cả các textareas trên một trang.
this.selectionEnd = s+1;
với this.selectionEnd = s + "\t".length;
. Sẽ tốt hơn nếu sử dụng một tham số biến hoặc hàm và lưu trữ ký tự thụt lề ở đó. Nhưng bạn đã biết phải thay thế cái gì bây giờ: Định +1
nghĩa bao nhiêu ký tự được di chuyển.
KeyboardEvent.keyCode
và KeyboardEvent.which
là tài sản không dùng nữa. Sử dụng KeyboardEvent.key
thay thế.
Như những người khác đã viết, bạn có thể sử dụng JavaScript để ghi lại sự kiện, ngăn chặn hành động mặc định (để con trỏ không dịch chuyển tiêu điểm) và chèn một ký tự tab.
Nhưng , vô hiệu hóa hành vi mặc định làm cho không thể di chuyển tiêu điểm ra khỏi vùng văn bản mà không sử dụng chuột. Người dùng mù tương tác với các trang web bằng bàn phím và không có gì khác - họ không thể thấy con trỏ chuột để làm bất cứ điều gì hữu ích với nó, vì vậy đó là bàn phím hoặc không có gì. Phím tab là cách chính để điều hướng tài liệu và đặc biệt là các biểu mẫu. Ghi đè hành vi mặc định của phím tab sẽ khiến người dùng khiếm thị không thể di chuyển tiêu điểm sang thành phần biểu mẫu tiếp theo.
Vì vậy, nếu bạn đang viết một trang web cho nhiều đối tượng, tôi khuyên bạn không nên làm điều này mà không có lý do thuyết phục và cung cấp một số loại thay thế cho người dùng mù không mắc kẹt trong vùng văn bản.
Đối với những gì nó có giá trị, đây là oneliner của tôi, cho những gì tất cả các bạn đã nói về chủ đề này:
<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>
Thử nghiệm trong các phiên bản mới nhất của Chrome, Firefox, Internet Explorer và Edge.
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;}}
Đây là phiên bản của tôi về điều này, hỗ trợ:
$(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>
Cách hiện đại mà cả hai đều đơn giản và không mất khả năng hoàn tác (Ctrl + Z) những thay đổi cuối cùng.
$('#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));
}
});
Thông tin thêm về execCommand
:
Như đã chỉ ra trong nhận xét (và trong khi đây từng là một giải pháp "hiện đại" ), tính năng này đã trở nên lỗi thời. Trích dẫn các tài liệu:
Tính năng này đã lỗi thời. Mặc dù nó vẫn có thể hoạt động trong một số trình duyệt, nhưng việc sử dụng nó không được khuyến khích vì nó có thể bị xóa bất cứ lúc nào. Cố gắng tránh sử dụng nó.
indent-textarea
một giải pháp trình duyệt chéo sử dụng phương pháp này + dự phòng trong Firefox.
document.execCommand
chỉ được bật sau khi cài đặt document.designMode = "on";
. Tôi có thể lấy văn bản để viết thành các yếu tố có .contentEditable = 'true'
. Tuy nhiên, khi tôi cố gắng thực hiện điều này trên một vùng văn bản, textNode được chèn sẽ được đặt ngay trước vùng văn bản trong tài liệu (thay vì vào vùng văn bản). Hãy cố gắng giúp Mozilla tìm ra điều này ở đây .
execCommand
): Feature Tính năng này đã lỗi thời. Mặc dù nó vẫn có thể hoạt động trong một số trình duyệt, nhưng việc sử dụng nó không được khuyến khích vì nó có thể bị xóa bất cứ lúc nào. Cố gắng tránh sử dụng nó. '
Tôi đã nhanh chóng cố gắng sử dụng câu trả lời của @ kasdega trong môi trường AngularJS, không có gì tôi cố gắng có thể khiến Angular hành động thay đổi. Vì vậy, trong trường hợp nó được sử dụng cho người qua đường, đây là bản viết lại mã của @ kasdega, kiểu AngularJS, phù hợp với tôi:
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');
}
});
};
});
và:
<textarea ng-model="mytext" ng-allow-tab></textarea>
element.triggerHandler('change');
, nếu không thì mô hình sẽ không được cập nhật (vì element.triggerHandler('change');
tôi nghĩ vậy.
Bạn phải viết mã JS để bắt phím TAB và chèn một loạt khoảng trắng. Một cái gì đó tương tự như những gì JSFiddle làm.
Kiểm tra bí ẩn jquery :
HTML :
<textarea id="mybox">this is a test</textarea>
JavaScript :
$('#mybox').live('keydown', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
alert('tab pressed');
}
});
event.preventDefault();
e.keyCode || e.which
.
Tập lệnh xác định nhiều dòng dựa trên giải pháp @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;
}
});
start === end
.
Giải pháp này cho phép lập bảng trong toàn bộ lựa chọn như trình soạn thảo mã điển hình của bạn và cũng không bỏ qua lựa chọn đó. Tuy nhiên, tôi chưa tìm ra cách triển khai tab shift khi không có lựa chọn nào.
$('#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 đơn giản : jsfiddle.net/jwfkbjkr
Dựa trên tất cả những gì mọi người đã nói ở đây về các câu trả lời, đây chỉ là sự kết hợp của phím tắt (không phải là keyup) + notifyDefault () + chèn một ký tự tab vào dấu mũ. Cái gì đó như:
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
insertAtCaret('txt', '\t')
}
Câu trả lời trước đó có jsfiddle hoạt động nhưng nó đã sử dụng cảnh báo () khi tắt phím. Nếu bạn loại bỏ cảnh báo này, thì nó đã không hoạt động. Tôi vừa thêm một chức năng để chèn một tab ở vị trí con trỏ hiện tại trong vùng văn bản.
Đây là một jsfiddle làm việc cho cùng: http://jsfiddle.net/nsHGZ/
Tôi thấy chủ đề này không được giải quyết. Tôi đã mã hóa điều này và nó hoạt động rất tốt. Nó chèn một bảng vào chỉ mục con trỏ. Không sử dụng 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>
Tôi đã tạo một cái mà bạn có thể truy cập với bất kỳ yếu tố textarea nào bạn thích:
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;
}
}
Và yếu tố sẽ như thế này:
<textarea onkeydown="textControl(this,event)"></textarea>
Cách đơn giản nhất mà tôi tìm thấy để làm điều đó trong các trình duyệt hiện đại với vanilla JavaScript là:
<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>
Lưu ý rằng tôi đã sử dụng nhiều tính năng ES6 trong đoạn trích này vì mục đích đơn giản, có lẽ bạn sẽ muốn dịch mã nó (với Babel hoặc TypeScript) trước khi triển khai nó.
Các câu trả lời trên tất cả xóa sạch lịch sử. Đối với bất kỳ ai đang tìm kiếm một giải pháp không làm điều đó, tôi đã dành giờ cuối cùng để mã hóa phần sau cho 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);
});
};
Nói tóm lại, các tab được chèn vào đầu các dòng được chọn.
JSFiddle: http://jsfiddle.net/iausallc/5Lnabspr/11/
Gist: https://gist.github.com/iautomation/e53647be326cb7d7112d
Ví dụ sử dụng: $('textarea').enableTabs('\t')
Nhược điểm: Chỉ hoạt động trên Chrome.
Có một thư viện trên Github để hỗ trợ tab trong textareas của bạn bởi wjbryant: Ghi đè tab
Đây là cách nó hoạt động:
// get all the textarea elements on the page
var textareas = document.getElementsByTagName('textarea');
// enable Tab Override for all textareas
tabOverride.set(textareas);
Là một tùy chọn cho mã của kasdega ở trên, thay vì nối thêm tab vào giá trị hiện tại, thay vào đó bạn có thể chèn các ký tự tại điểm con trỏ hiện tại. Điều này có lợi ích của:
nên thay thế
// set textarea value to: text before caret + tab + text after caret
$(this).val($(this).val().substring(0, start)
+ "\t"
+ $(this).val().substring(end));
với
// set textarea value to: text before caret + tab + text after caret
document.execCommand("insertText", false, ' ');
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;
}
}
Hãy thử hàm jQuery đơn giản này:
$.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();
Tôi đã phải tạo một hàm để làm tương tự, Nó rất đơn giản để sử dụng, chỉ cần sao chép mã này vào tập lệnh của bạn và sử dụng: enableTab( HTMLElement )
HTMLelement là một cái gì đó giống như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}}}
Mỗi đầu vào một phần tử textarea có một sự kiện onkeydown. Trong trình xử lý sự kiện, bạn có thể ngăn phản ứng mặc định của phím tab bằng cách sử dụng event.preventDefault () bất cứ khi nào event.keyCode là 9.
Sau đó đặt một dấu hiệu tab ở đúng vị trí:
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>
$("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
}
});
Kịch bản độc lập đơn giản:
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;
}
}
}
Nếu bạn thực sự cần các tab, hãy sao chép một tab từ word hoặc notepad và dán nó vào hộp văn bản nơi bạn muốn
1 2 3
12 22 33
Thật không may, tôi nghĩ rằng họ xóa các tab khỏi các nhận xét này :) Nó sẽ hiển thị dưới dạng% 09 trong POST hoặc GET của bạn