Eu tenho uma área de texto html simples do meu lado. Agora, se você clicar na guia, ela será direcionada para o próximo campo. Gostaria de fazer com que o botão da guia recue alguns espaços. Como posso fazer isso? Obrigado.
Eu tenho uma área de texto html simples do meu lado. Agora, se você clicar na guia, ela será direcionada para o próximo campo. Gostaria de fazer com que o botão da guia recue alguns espaços. Como posso fazer isso? Obrigado.
Respostas:
Tomando emprestado de outras respostas para perguntas semelhantes (postadas abaixo) ...
$(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: Como capturar o pressionamento de tecla TAB dentro de uma caixa de texto
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;
}
}
}
Esta solução não requer jQuery e ativará a funcionalidade da guia em todas as áreas de texto em uma página.
this.selectionEnd = s+1;
por this.selectionEnd = s + "\t".length;
. Seria mais limpo usar um parâmetro de variável ou função e armazenar os caracteres de indentação lá. Mas você sabe o que substituir agora: O +1
define quantos caracteres o cursor é movido.
KeyboardEvent.keyCode
e KeyboardEvent.which
são propriedades descontinuadas. Use em KeyboardEvent.key
vez disso.
Como outros escreveram, você pode usar JavaScript para capturar o evento, impedir a ação padrão (para que o cursor não mude o foco) e inserir um caractere de tabulação.
Porém , desabilitar o comportamento padrão torna impossível mover o foco para fora da área de texto sem usar o mouse. Usuários cegos interagem com páginas da Web usando o teclado e nada mais - eles não podem ver o ponteiro do mouse para fazer algo útil com ele, por isso é teclado ou nada. A tecla Tab é a principal maneira de navegar no documento, especialmente nos formulários. A substituição do comportamento padrão da tecla tab tornará impossível para os usuários cegos mover o foco para o próximo elemento do formulário.
Portanto, se você estiver escrevendo um site para um público amplo, recomendo que não faça isso sem um motivo convincente e forneça algum tipo de alternativa para usuários cegos que não os prendam na área de texto.
Para o que vale, aqui está o meu oneliner, para o que todos vocês têm falado neste tópico:
<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>
Teste nas últimas edições do Chrome, Firefox, Internet Explorer e 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;}}
Aqui está a minha versão disso, suporta:
$(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>
Maneira moderna de que ambos são diretos e não perdem a capacidade de desfazer (Ctrl + Z) as últimas alterações.
$('#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));
}
});
Mais sobre execCommand
:
Conforme apontado no comentário (e embora essa tenha sido uma solução "moderna" ), o recurso ficou obsoleto. Citando os documentos:
Esse recurso está obsoleto. Embora ainda possa funcionar em alguns navegadores, seu uso é desencorajado, pois pode ser removido a qualquer momento. Tente evitar usá-lo.
indent-textarea
uma solução para vários navegadores que use esse método + um fallback no Firefox.
document.execCommand
somente é ativado após a configuração document.designMode = "on";
. Eu sou capaz de obter texto para escrever em elementos que têm .contentEditable = 'true'
. No entanto, quando tento fazer isso em uma área de texto, o textNode inserido é colocado logo antes da área de texto no documento (em vez de na área de texto). Por favor, tente ajudar a Mozilla a descobrir isso aqui .
execCommand
): 'Esse recurso está obsoleto. Embora ainda possa funcionar em alguns navegadores, seu uso é desencorajado, pois pode ser removido a qualquer momento. Tente evitar usá-lo.
Eu estava chegando a lugar nenhum rapidamente tentando usar a resposta de @ kasdega em um ambiente AngularJS, nada do que tentei parecia capaz de fazer o Angular agir sobre a mudança. Portanto, caso seja de alguma utilidade para quem passa, aqui está uma reescrita do código do @ kasdega, estilo AngularJS, que funcionou para mim:
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');
}
});
};
});
e:
<textarea ng-model="mytext" ng-allow-tab></textarea>
element.triggerHandler('change');
, caso contrário, o modelo não será atualizado (por causa do element.triggerHandler('change');
que eu penso.
Você precisa escrever o código JS para capturar a tecla TAB e inserir vários espaços. Algo semelhante ao que o JSFiddle faz.
Verificar jquery fiddle :
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
.
Script de indetação de várias linhas baseado na solução @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
.
Esta solução permite separar uma seleção inteira como o seu típico editor de código e desmarcar essa seleção também. No entanto, ainda não descobri como implementar a tecla shift quando não há seleçã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 simples : jsfiddle.net/jwfkbjkr
Com base no que as pessoas têm a dizer aqui nas respostas, é apenas uma combinação de pressionamento de tecla (não ajuste de tecla) + preventDefault () + inserir um caractere de tabulação no cursor. Algo como:
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
insertAtCaret('txt', '\t')
}
A resposta anterior tinha um jsfiddle funcionando, mas usava um alert () no pressionamento de tecla. Se você remover este alerta, ele não funcionou. Acabei de adicionar uma função para inserir uma guia na posição atual do cursor na área de texto.
Aqui está o trabalho do jsfiddle para o mesmo: http://jsfiddle.net/nsHGZ/
Eu vejo que este assunto não está resolvido. Eu codifiquei isso e está funcionando muito bem. Ele insere uma tabulação no índice do cursor. Sem usar 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>
Eu criei um que você pode acessar com qualquer elemento de área de texto que desejar:
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;
}
}
E o elemento ficaria assim:
<textarea onkeydown="textControl(this,event)"></textarea>
A maneira mais simples de encontrar isso em navegadores modernos com JavaScript vanilla é:
<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>
Observe que eu usei muitos recursos do ES6 neste snippet por uma questão de simplicidade. Você provavelmente desejará transpilar (com Babel ou TypeScript) antes de implantá-lo.
As respostas acima limpam o histórico de desfazer. Para quem procura uma solução que não faça isso, passei a última hora codificando o seguinte para o 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);
});
};
Em resumo, as guias são inseridas no início das linhas selecionadas.
JSFiddle: http://jsfiddle.net/iausallc/5Lnabspr/11/
Gist: https://gist.github.com/iautomation/e53647be326cb7d7112d
Exemplo de uso: $('textarea').enableTabs('\t')
Contras: funciona apenas no Chrome como está.
Há uma biblioteca no Github para suporte a guias em suas áreas de texto por wjbryant: Substituição de guias
É assim que funciona:
// get all the textarea elements on the page
var textareas = document.getElementsByTagName('textarea');
// enable Tab Override for all textareas
tabOverride.set(textareas);
Como uma opção para o código do kasdega acima, em vez de anexar a guia ao valor atual, você pode inserir caracteres no ponto atual do cursor. Isso tem o benefício de:
então substitua
// set textarea value to: text before caret + tab + text after caret
$(this).val($(this).val().substring(0, start)
+ "\t"
+ $(this).val().substring(end));
com
// 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;
}
}
Experimente esta função jQuery simples:
$.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();
Eu tive que criar uma função para fazer o mesmo, é simples de usar, basta copiar este código para o seu script e usar: enableTab( HTMLElement )
HTMLelement sendo algo comodocument.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}}}
Cada entrada de um elemento de área de texto possui um evento onkeydown. No manipulador de eventos, você pode impedir a reação padrão da tecla tab usando event.preventDefault () sempre que event.keyCode for 9.
Em seguida, coloque um sinal de tabulação na posição correta:
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
}
});
Script autônomo simples:
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;
}
}
}
Se você realmente precisa de guias, copie uma guia da palavra ou do bloco de notas e cole-a na caixa de texto onde deseja
1 2 3
12 22 33
Infelizmente, acho que eles removeram as guias desses comentários :) Ele será exibido como% 09 no seu POST ou GET