Diferenças de eventos HTML nos navegadores

18 respostas
D

Estou com um problema devido às diferenças impostas pelos navegadores.

Fiz um exemplo com um simples HTML e um formulário, onde um dos campos possui tratamente dos eventos (onBlur, onFocus, etc). O IE (6.0.2900.2180 SP2) e o Firefox (2.0.0.9) se comportam de maneira diferente.

O teste ocorreu da seguinte maneira nos dois navegadores, com a execução dos respectivos eventos:

1) Foco no campo Name
2) TAB mudando foco para campo Age (onFocus, onKeyUp - ambos navegadores)
3) TAB mudando foco para campo E-mail (onKeyDown, onBlur - IE / onKeyDown, onKeyPress, onBlur - FF)
4) Click com o mouse sobre o campo Age (onFocus - ambos)
5) Click com o mouse fora do campo Age (onBlur - ambos)

Por conta do Firefox (FF) executar o onKeyPress a mais, quando o IE não executa, me causa um problema, por causa da ação que executo (javascript) no onKeyPress.

O código HTML é este:

<html>
<head>
 <title>Testing Firefox Bug</title>
<script language="JavaScript">
function show(msg) {
  document.forms[0].log.value += msg + '\n';
}
</script>
</head>
<body>
<form name="frm" method="post" action="">
 Name: <input type="text" name="name" id="name" > <br>
 Age: <input type="text" name="age" id="age" onFocus="show('onFocus');" onBlur="show('onBlur');" onChange="show('onChange');" onKeyUp="show('onKeyUp');" onKeyDown="show('onKeyDown');" onKeyPress="show('onKeyPress');" > <br>
 E-mail: <input type="text" name="email" id="email"> <br>
 <input type="submit" name="OK" value="OK" id="ok"> <input type="reset" name="Cancel" value="Cancel" id="cancel">
<br><br>
<textarea name="log" id="log" rows="25" size="30"></textarea>
</form>
</body>
</html>

As imagens mostram o comportamento diferente nos dois navegadores.

Essa falta de padrão irrita!



18 Respostas

C

É gambiarra, mas acho que dá pra você usar fireEvent() quando o browser for IE, lançando um novo onKeyPress.

Algo como

function doFire(objID) {
    var newEvt = document.createEventObject()
    newEvt.input = document.getElementById('email');
    document.getElementById(objID).fireEvent('onkeypress', newEvt);
}
D

Eu NÃO quero que o onKeyPress seja lançado. Enfim, não vou ficar mudando milhares de eventos em milhares de campos e formulários.

D

Em alguns campos, no evento onKeyPress eu chamo uma função JavaScript que não permite a digitação de caracteres não numéricos.

A função é assim:

var v_elem_obj = null;

function avoidNotNumber( elem ) {
    v_elem_obj = elem;
    setTimeout("execAvoidNotNumber()",1);
}

function execAvoidNotNumber() {
    v_elem_obj.value = removeNonDigits(v_elem_obj.value);
}

Para que ela funcione, tem que chamar o método via setTimeout. Senão os navegadores não barram a digitação direito.

Eu poderia usar o onKeyUp em vez, porém, quando o usuário deixa um botão pressionado, ele permite a digitação do caracter barrado, porém exclui esses caracteres ao final.

C

Não entendi uma coisa… vc está setando estes eventos em todos os inputs dos seus formulários, de forma global?
(via javascript no window.load ou algo assim) ou está fazendo como no seu exemplo, setando o evento dentro da tag html?

S

Coloca estas duas linhas no seu arquivo html…

substituindo a tag por esta completa abaixo, e verifica o que acontece…

Aqui na minha aplicação na empresa funcionou !!!

S
# function show(msg) {  
#   document.forms[0].log.value += msg + '\n';  
# }  
# </script>  
# </head>  
# <body>  
# <form name="frm" method="post" action="">

Creio que o nome na função javascript esteja errada, deveria ser desta forma;

# function show(msg) {  
#   document.frm[0].log.value += msg + '\n';  
# }  
# </script>  
# </head>  
# <body>  
# <form name="frm" method="post" action="">
D

cassio:
Não entendi uma coisa… vc está setando estes eventos em todos os inputs dos seus formulários, de forma global?
(via javascript no window.load ou algo assim) ou está fazendo como no seu exemplo, setando o evento dentro da tag html?

Em cada campo, como no exemplo. Na verdade é uma TAG que eu criei, que estende as tags do Struts, para trabalhar com campo de tipos específicos (CEP, CNPJ, CPF, DATA, etc).

D

O que é que funcionou???

E seu javascritp acima está errado. Não é frm[0] e sim forms[0].

C

Putz… não consigo pensar em nenhuma solução que não seja gambiarra ou vá sujar o código…
Dentro da tag que criou você poderia tirar o evento de dentro da tag html e colocar a criação do onkeypress quando necessário através de um <script> logo após seu campo… poderia usar um novo atributo para o onkeypress tipo <seuPrefixo:suaTag onkeypress=“true” onkeypressFunction=“blabla()” />
Mas não é possível Daniel, deve ter jeito mais simples…

D

Faça um teste você mesmo no IE e no FF com o HTML abaixo.
Coloque aqui as versões utilizadas e o resultado da formatação do campo "Data Nasc".

&lt;html&gt;
&lt;head&gt;
 &lt;meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/&gt;
 &lt;script language="JavaScript" type="text/javascript"&gt; 
var v_elem_obj = null;

function avoidNotNumber( elem ) {
    v_elem_obj = elem;
    setTimeout("execAvoidNotNumber()",1);
}

function execAvoidNotNumber() {
    v_elem_obj.value = removeNonDigits(v_elem_obj.value);
}

function unmask( elem ) {
    elem.value = removeNonAlphanumeric(elem.value);
    elem.select();
}

function maskDate( elem ) {
    var ret = formatarData(elem.value);
    if( ret != null && ret != "" ) {
        elem.value = ret;
    }
}

function copyElementValueUnmasked( source, destination ) {
    destination.value = removeNonAlphanumeric(source.value);
}

function formatarData( value ) {
    var re = /^(\d{2})(\/|-)(\d{2})(\/|-)(\d{4})$/;
    if( re.test(value) ) {
        return value;
    }
    var re = /^\d{8}$/;
    if( re.test(value) ) {
        var re2 = /^(\d{2})(\d{2})(\d{4})$/;
        return value.replace(re2,"$1/$2/$3");
    }
    return "";
}

function removeNonDigits( value ) {
    return value.replace(/\D/g,"");
}

function removeNonAlphanumeric( value ) {
    return value.replace(/\W/g,"");
}

function getElement(doc, id) {
    var elem = null;
    //tem que tratar browsers diferentemente
    if( doc.getElementById ) { // DOM3 = IE5, NS6
        elem = doc.getElementById(id);
    } else if( doc.layers ) { // Netscape 4
        elem = doc.id;
    } else { // IE 4
        elem = doc.all.id;
    }
    return elem;
}

function capitalize(elem) {
  elem.value = elem.value.toUpperCase();
}
 &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h3&gt;Cadastro&lt;/h3&gt;
&lt;form name="frm2" method="post" action="teste.htm"&gt;
&lt;fieldset&gt;
&lt;legend&gt;Dados Pessoais&lt;/legend&gt;
&lt;table border="0" cellspacing="1" cellpadding="2"&gt;
 &lt;tr&gt;
  &lt;td&gt;&lt;label for="texto1"&gt;Nome&lt;/label&gt;&lt;/td&gt;
  &lt;td&gt;&lt;input type="text" name="nome" maxlength="60" size="50" onblur="capitalize(this);"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td&gt;&lt;label for="data1"&gt;Data Nasc.&lt;/label&gt;&lt;/td&gt;
  &lt;td&gt;&lt;input type="text" name="data1_masked" maxlength="10" size="10" onkeypress="avoidNotNumber(this);" onblur="maskDate(this);copyElementValueUnmasked(this,getElement(document,'idData1_hidden'));" onfocus="unmask(this);" id="idData1"&gt;
      &lt;input type="hidden" name="data1" id="idData1_hidden"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td&gt;&lt;label for="texto1"&gt;E-mail&lt;/label&gt;&lt;/td&gt;
  &lt;td&gt;&lt;input type="text" name="email" maxlength="60" size="50"&gt;&lt;/td&gt;
 &lt;/tr&gt;
&lt;/table&gt;
&lt;/fieldset&gt;
&lt;hr/&gt;
&lt;div align="right"&gt;&lt;input type="submit" value="Salvar"&gt; &lt;input type="reset" value="Limpar"&gt;&lt;/div&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
C

:arrow: firefox versão 2.0.0.8
Formatou o nascimento como dd/mm/yyyy quando eu cliquei fora do campo. Pressionando o tab ele piscou formatado mas voltou a ficar sem formatação.

:arrow: IE 6.0.37
Não formatou nem com mouse, nem com tab

D

cassio:
:arrow: firefox versão 2.0.0.8
Formatou o nascimento como dd/mm/yyyy quando eu cliquei fora do campo. Pressionando o tab ele piscou formatado mas voltou a ficar sem formatação.

Como esperado… ocorre o mesmo aqui. Aliás, o Firefox trunca o valor do campo para o tamanho definido em maxlength, ou seja, a data formatada tem 10 caracteres, portanto, aqui (FF 2.0.0.9, atualizado para 2.0.0.10) ele corta os dois últimos caracteres fora.

cassio:
:arrow: IE 6.0.37
Não formatou nem com mouse, nem com tab

Deu erro de JavaScript? Aqui funciona!

C

Não tenho IE aqui em casa, amanhã repito os testes no trabalho :slight_smile:

C

Bom, pensei no código abaixo. Óbvio que não é a solução mais elegante, mas ao que parece dá pra manter a compatibilidade… não testei no IE ainda, mas no firefox funfou bem, tanto com blur com tab (por isso o keyCode 9) como com blur pelo mouse.

function avoidNotNumber( evt, elem ) {
	if(evt.keyCode && evt.keyCode != 9) {
		v_elem_obj = elem;
		setTimeout("execAvoidNotNumber()",1);
	}
}

E no HTML

input type="text" name="data1_masked" maxlength="10" size="10" onkeypress="avoidNotNumber(event,this);" onblur="maskDate(this);copyElementValueUnmasked(this,getElement(document,'idData1_hidden'));" onfocus="unmask(this);" id="idData1"&gt;

veja se no IE também funciona, não tenho certeza se o objeto event é válido no IE também.

D

Boaaaaa... aqui funcionou.
Alterações que eu fiz:

function isTabKeyPressed( evt ) {
    var keyCode = evt.keyCode ? evt.keyCode : evt.which ? evt.which : evt.charCode;
    if( keyCode && keyCode == 9 /* TAB */ ) {
        return true;
    }
    return false;
}

function avoidNotNumber( elem, evt ) {
    if( isTabKeyPressed(evt) ) {
        return;
    }
    v_elem_obj = elem;
    setTimeout("execAvoidNotNumber()",1);
}
C

Chato que foi necessário criar uma nova função pra organizar melhor as coisas né, mas que bom que deu certo :slight_smile:

D

Logo devo lançar o que estou fazendo para o Struts como projeto Open Source.
Embora seja pra versão antiga do Struts (está homologado para Struts 1.1, mas deve funcionar até a versão 1.9), muita gente ainda usa como legado.

C

danieldestro:
Logo devo lançar o que estou fazendo para o Struts como projeto Open Source.
Embora seja pra versão antiga do Struts (está homologado para Struts 1.1, mas deve funcionar até a versão 1.9), muita gente ainda usa como legado.

Bom saber que contribuí para algo open source :slight_smile:

Criado 28 de novembro de 2007
Ultima resposta 29 de nov. de 2007
Respostas 18
Participantes 3