Front End

7 jul, 2014

Não nomeie as suas entradas como “action” ou “submit”!

Publicidade

A maioria dos navegadores tem um bug que na verdade não é um bug. Ele é colocados lá de propósito, mas se você (ou outra pessoa que estiver escrevendo o código HTML) fizer alguma coisa na forma certa (leia-se “ERRADO!”), ele poderia estragar tudo completamente. Para ser mais específico: se você atribuiu às suas tags input um atributo name ou id de “action” ou “submit”, você pode provocar alguns bugs que estavam muito bem escondidos.

Introdução ao “bug”

No ano passado, eu li Secrets of the JavaScript Ninja, de John Resig e Bear Bibeault. É definitivamente um ótimo livro, se você estiver pensando em escrever JavaScript de forma bem simples e básica. De qualquer forma, no capítulo 11, algo me chamou a atenção. Como o resultado de uma característica que eles se referiram como “greedy IDs”, se você tiver um elemento input com um id e/ou um atributo name dentro de um form, você vai conseguir referenciar diretamente aquele input como uma propriedade do formulário.

<form id="form" action="url">
    <input type="text" id="textboxid" name="textboxname">
</form>

// Grab the form
var form = document.getElementById('form');
 
// Reference the text box directly from the form by its ID or name
form.textboxid;   // -> The input element
form.textboxname; // -> The input element

Essa é uma ideia muito legal, só que tudo isso não é necessário, uma vez que obter elementos pelo seu id ou name é bem simples. Além disso, se atente para uma coisa muito importante: se o formulário já tem uma propriedade com a mesma chave como id/name do input, essa propriedade vai ser substituída por uma referência ao elemento input.

Isso se torna especialmente complicado se você tiver inputs chamadas de “action” ou “submit” e estiver tentando controlar os envios com JavaScript. Agora, se você precisa conhecer a URL que vai submeter (via form.action), ou se quiser apenas enviar o formulário programaticamente (via form.submit), você vai obter um valor muito errado ou um erro, respectivamente.

Solução alternativa

Eu, pessoalmente, nunca achei que fosse passar por essa situação, mas acabei me deparando com ela em algum momento. Provavelmente, a maneira mais simples de resolver o problema é renomear seu inputs, mas infelizmente eu não tive acesso ao HTML, e às vezes você não vai ter também. Existe também a chance de que outro código se baseie naquele id/nome para outros fins. Bem, se você não tiver nenhuma maneira de corrigir o HTML, não existe outra maneira de contornar isso.

Essa correção só funciona para as propriedades do formulário que são funções. Todas as que não são ficarão travadas, mesmo que você tente mudar o nome/id do elemento input dinamicamente com JavaScript. De qualquer forma, para trabalhar em torno de funções (como submit) que estejam sendo substituídas, você pode tirar a função do protótipo, e chamá-la com um contexto do form que você deseja usar.

<form id="form" action="url">
    <input type="text" id="submit">
</form>

// Grab the form
var form = document.getElementById('form');
 
// Try to submit it the normal way
form.submit(); // Nope, that's an error
 
// Try to submit using the prototype
HTMLFormElement.prototype.submit.call(form); // Yay! It worked!

Não tentei isso em navegadores mais antigos, mas deve funcionar em qualquer um que suporte o bom e velho HTML4, uma vez que o HTMLFormElement foi inicialmente no DOMLevel 1 Specification.

Conclusão

Estou um pouco surpreso que uma solução alternativa nunca tenha sido sugerida no livro. Eles meio que o ignoraram, dizendo que devemos evitar o uso desses names/ids:

“Felizmente, podemos evitar esse problema em nossa própria marcação, evitando valores id simples que podem entrar em conflito com nomes das propriedades padrão, e podemos incentivar outras pessoas a fazer o mesmo. O valor submit é para ser especialmente evitado para valores id e name, já que é uma fonte comum de comportamento frustrante e desconcertante de bug”.

Mesmo que esse seja, definitivamente, um bom conselho, daí o título deste artigo, nem sempre é evitável, por isso é bom ter uma forma simples de contornar alguns dos problemas. De qualquer forma, espero que você nunca precise usar essa solução alternativa.

***

Artigo traduzido com autorização do autor pela Redação iMasters. Publicado originalmente em http://www.joezimjs.com/javascript/dont-name-inputs-action-submit/