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.
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;varend=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 againthis.selectionStart =this.selectionEnd = start +1;}});
"$ (this) .get (0) .selectionStart". Use apenas "this.selectionStart"
Bohdan Yurov
Você pode fazer isso funcionar com 4 espaços em vez de a \ t? Se você substituir \ t por "", ele inserirá os espaços, mas deixará o cursor para trás.
Sinaesthetic
@Sinaesthetic - resposta tardia, mas para mover o cursor, ajuste a última linha a ser 'start + 4' em vez de 'start + 1'
nevada_scout
4
Normalmente, não copio o código diretamente do Stackoverflow e o colo no meu projeto para que funcione, mas quando o faço, esse código é esse. Obrigado por isso.
Flat Cat
10
Isso interrompe o recurso de desfazer do navegador (Ctrl + z).
01AutoMonkey 23/03
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;}}}
Esta solução não requer jQuery e ativará a funcionalidade da guia em todas as áreas de texto em uma página.
Você pode fazer isso funcionar com 4 espaços em vez de a \ t? Se você substituir \ t por "", ele inserirá os espaços, mas deixará o cursor para trás.
Sinaesthetic
1
@ Sinestésico: sim, você pode alterar a tabulação para espaços, mas é necessário adaptar um pouco o código (existem 3-4 novas letras em vez de uma). A outra alternativa é o tamanho da guia CSS.
Adrian Maire
@ Sinestésico Sim, basta substituir a última linha 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 +1define quantos caracteres o cursor é movido.
StanE 13/10/16
2
KeyboardEvent.keyCodee KeyboardEvent.whichsão propriedades descontinuadas. Use em KeyboardEvent.keyvez disso.
Константин Ван
48
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.
obrigado. Não pretendo parecer rude, mas não sabia que as pessoas cegas usavam computadores. Eu manterei isso em mente #
770483
10
Tudo bem, muitas pessoas não sabem; é apenas fora da experiência deles. Aqui está uma introdução: webaim.org/intro
Will Martin
Sim, é uma péssima ideia se este é um site para o público em geral. Além dos usuários do leitor de tela, existem muitos outros usuários que, por várias razões, precisam ou optam por navegar com o teclado. Capturar a tecla Tab fará com que o formulário seja pelo menos irritante e possivelmente inutilizável para esses usuários.
steveax
6
Talvez use control + tab. Isso aumentará a capacidade do navegador para outras guias (páginas da web), mas os usuários podem simplesmente sair da caixa de texto e controlar a guia para a outra página. Deve ter uma dica na página, use ctrl + tab para tab.
Joseph McIntyre
Obrigado @WillMartin Informações muito valiosas. Ia implementar a mesma coisa em todo o meu blog para todas as áreas de texto sem considerar esse ponto crucial.
28816 Imran
40
Para o que vale, aqui está o meu oneliner, para o que todos vocês têm falado neste tópico:
Como posso modificar esse código para usar 4 espaços em vez de uma guia? Eu tentei fazer o & nbsp; quatro vezes, mas ainda o converteu em um único espaço.
precisa saber é o seguinte
5
NiCk, por favor, diga à minha esposa. jiaweizhang, substitua '\ t' com '<4 espaços>' e 1 com 4.
elgholm
1
A melhor resposta!
Marco Demaio
1
Muito legal, aqui está o contrário via 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
Aqui está a minha versão disso, suporta:
guia + guia shift
mantém a pilha de desfazer para inserções simples de caracteres de tabulação
suporta recuo / desindentamento da linha de bloco, mas os resíduos desfazem a pilha
seleciona corretamente linhas inteiras quando o bloco é recuado /
suporta recuo automático ao pressionar enter (mantém a pilha de desfazer)
use o suporte para cancelar a tecla Escape na próxima guia / tecla Enter (para pressionar Escape e depois sair)
Funciona no Chrome + Edge, outros não testados.
$(function(){var enabled =true;
$("textarea.tabSupport").keydown(function(e){// Escape key toggles tab on/offif(e.keyCode==27){
enabled =!enabled;returnfalse;}// Enter Key?if(e.keyCode ===13&& enabled){// selection?if(this.selectionStart ==this.selectionEnd){// find start of the current linevar 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 visiblethis.blur();this.focus();returnfalse;}}}// Tab key?if(e.keyCode ===9&& enabled){// selection?if(this.selectionStart ==this.selectionEnd){// These single character operations are undoableif(!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 linesvar 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 textvar lines = text.substr(selStart, selEnd - selStart).split('\n');// Insert tabsfor(var i=0; i<lines.length; i++){// Don't indent last line if cursor at start of lineif(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);elseif(lines[i].startsWith(" "))
lines[i]= lines[i].substr(4);}else
lines[i]="\t"+ lines[i];}
lines = lines.join('\n');// Update the text areathis.value = text.substr(0, selStart)+ lines + text.substr(selEnd);this.selectionStart = selStart;this.selectionEnd = selStart + lines.length;}returnfalse;}
enabled =true;returntrue;});});
textarea
{width:100%;height:100px;tab-size:4;}
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><textareaclass="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>
Isso funciona sem jQuery com um pouco de trabalho. Verifique youmightnotneedjquery.com para obter ajuda. Definitivamente, a melhor resposta aqui também.
Jamon Holmgren
10
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));}});
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.
Esta é a única resposta correta neste momento. Muito obrigado. 🙏
Chris Calo
2
Infelizmente, não há suporte para o Firefox. Tente indent-textareauma solução para vários navegadores que use esse método + um fallback no Firefox.
Fregante 12/04/19
No Firefox, document.execCommandsomente é 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 .
Lonnie Best
Esteja ciente de que isso não é mais considerado 'moderno', a página que você vinculou observa (sobre 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.
kasimir
9
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:
É muito importante a chamada element.triggerHandler('change');, caso contrário, o modelo não será atualizado (por causa do element.triggerHandler('change');que eu penso.
Alvaro Flaño Larrondo
6
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.
Melhor solução até agora, mas provavelmente não deve criar uma seleção quando start === end.
MPEN
6
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;}});
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><textareaid="txtInput">
$(document).ready(function(){
$("#msgid").html("This is Hello World by JQuery");
});
</textarea>
Isso funciona bem, mas você pode pelo menos limitar a guia shift sem selecionar erros gerados. Eu fiz isso com o if (selected.length > 0) {...}Fiddle simples : jsfiddle.net/jwfkbjkr
3
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.
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
<textareaid="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 Tabthis.value.slice(cIndex)].join('');//Join with the end
event.stopPropagation();
event.preventDefault();//Don't quit the areathis.selectionStart=cIndex+1;this.selectionEnd=cIndex+1;//Keep the cursor in the right index}});</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:
Qual parte deste script está funcionando apenas no Chrome? É o "TextEvent"? help.dottoro.com/lagstsiq.php/#TextEvent Este site diz que também deve funcionar no IE9 + e no Safari. Como eu preciso disso para um aplicativo Chrome, isso é perfeito.
Andreas Linnert
@ Andreas Linnert, você está certo. Está documentado para funcionar no IE e no Safari. No entanto, no momento em que escrevi este artigo, o IE não funcionava para mim, e simplesmente não tinha tempo para investigar mais e não havia testado no Safari. Desculpas pela confusão. Estou feliz por ter ajudado.
iautomation
0
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 pagevar textareas = document.getElementsByTagName('textarea');// enable Tab Override for all textareas
tabOverride.set(textareas);
Não é uma resposta ruim, mas olhando para o código, ele usa praticamente as mesmas técnicas descritas em algumas das respostas aqui: github.com/wjbryant/taboverride/blob/master/src/… . Isso significa que ele não preserva o histórico de desfazer, que é o principal problema.
mihai 19/03
0
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:
permite inserir 4 espaços como alternativa à tabulação
desfazer e refazer funcionará com os caracteres inseridos (não com o OP)
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,' ');
$.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;returnfalse;}returntrue;});returnthis;};
$("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 )
O código é:
function enableTab(t){t.onkeydown=function(t){if(9===t.keyCode){var e=this.value,n=this.selectionStart,i=this.selectionEnd;returnthis.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:
$("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 Tabthis.value.slice(cIndex)].join('');//Join with the endevent.stopPropagation();event.preventDefault();//Don't quit the areathis.selectionStart=cIndex+1;this.selectionEnd=cIndex+1;//Keep the cursor in the right index}});
Eu acho que isso é uma resposta, ainda que muito ruim. Ele está sugerindo uma abordagem alternativa, ou seja, fornecer uma solução alternativa ao usuário final.
Respostas:
Tomando emprestado de outras respostas para perguntas semelhantes (postadas abaixo) ...
jQuery: Como capturar o pressionamento de tecla TAB dentro de uma caixa de texto
Como lidar com <tab> na área de texto?
http://jsfiddle.net/jz6J5/
fonte
Esta solução não requer jQuery e ativará a funcionalidade da guia em todas as áreas de texto em uma página.
fonte
this.selectionEnd = s+1;
porthis.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
eKeyboardEvent.which
são propriedades descontinuadas. Use emKeyboardEvent.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.
fonte
Para o que vale, aqui está o meu oneliner, para o que todos vocês têm falado neste tópico:
Teste nas últimas edições do Chrome, Firefox, Internet Explorer e Edge.
fonte
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:
fonte
Maneira moderna de que ambos são diretos e não perdem a capacidade de desfazer (Ctrl + Z) as últimas alterações.
Mais sobre
execCommand
:Editar:
Conforme apontado no comentário (e embora essa tenha sido uma solução "moderna" ), o recurso ficou obsoleto. Citando os documentos:
fonte
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çãodocument.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:
e:
fonte
element.triggerHandler('change');
, caso contrário, o modelo não será atualizado (por causa doelement.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 :
JavaScript :
fonte
event.preventDefault();
e.keyCode || e.which
.Script de indetação de várias linhas baseado na solução @kasdega.
fonte
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.
fonte
if (selected.length > 0) {...}
Fiddle simples : jsfiddle.net/jwfkbjkrCom 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:
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/
fonte
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
fonte
Mantenha pressionada a tecla ALT e pressione 0,9 no teclado numérico. Funciona no google-chrome
fonte
Eu criei um que você pode acessar com qualquer elemento de área de texto que desejar:
E o elemento ficaria assim:
fonte
A maneira mais simples de encontrar isso em navegadores modernos com JavaScript vanilla é:
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.
fonte
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:
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á.
fonte
Há uma biblioteca no Github para suporte a guias em suas áreas de texto por wjbryant: Substituição de guias
É assim que funciona:
fonte
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
com
fonte
fonte
Experimente esta função jQuery simples:
fonte
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 )
O código é:
fonte
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:
html
fonte
fonte
Script autônomo simples:
fonte
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
fonte