quarta-feira, 21 de dezembro de 2011

Hoje após duas horas desesperantes, descobri a solução para o problema do scrollTop no IE8, quando é usado dentro de um 'SELECT'.

Basicamente, no IE8 quando se adiciona um elemento 'OPTION', via Javascript a um 'SELECT' que seja do tipo 'multiple' (nota: estou a usar um 'size' de 10), não posiciona a scroll bar, de forma a mostrar o elemento 'OPTION' que foi inserido (já pré-selecionado).

Isto tem o inconveniente de o utilizador não se aperceber que o elemento foi realmente adicionado, se a combo não estiver na posição ideal.

Note-se que estou a inserir os elementos ordenados alfabeticamente, logo a inserção poderá ocorrer em qualquer posição, dependendo dos elementos já existentes e do elemento inserido.

Para corrigir este problema de usabilidade, defini o seguinte código após ter efectuado a inserção no 'SELECT', dentro de um objecto JS que o contém:

   // we have to do this, in order for IE8 to correctly scroll to the added element
if( option.selected)
{
var topScroll = 0;
if( this.select.length )
topScroll = index * (this.select.scrollHeight / this.select.length );

this.select.scrollTop = topScroll; // <=- linha problemática
}


No entanto, após fazer debug da coisa, a 'linha problemática' aparentemente não executa !!!
Isto é, mesmo que o valor topScroll seja diferente de zero, o campo 'this.select.scrollTop' fica intocado.
É como se a instrução nunca tivesse sido executada !!!

Após perder umas centenas de neurónios, reparei que se eu forçar o valor no debugger a correcção funcionava !

Após mais algumas tentativas, para perceber o problema, cheguei ao momento Eureka!

O IE8, pega de empurrão!

Isto é a solução é insistir à canzana ! :)
Ou seja, repetir a instrução de atribuição !

   // we have to do this, in order for IE8 to correctly scroll to the added element
if( option.selected)
{
var topScroll = 0;
if( this.select.length )
topScroll = index * (this.select.scrollHeight / this.select.length );

this.select.scrollTop = topScroll;
this.select.scrollTop = topScroll; // WE MUST DUPLICATE THIS LINE, due to an IE8 Bug !
}


Incrível, mas é verdade ! E assim já funciona como esperado e é inócuo para os outros browsers, como seria de esperar.

quinta-feira, 22 de setembro de 2011

Java decompiler para o Eclipse

O Eclipse Java Decompiler pode dar jeito, quando ao meio do debug, nos deparamos com uma classe de uma lib (jar) qualquer, da qual não temos a source disponível.
Permite fazer o decompile da class enquanto fazemos debug, para determinar a fonte do problema.

terça-feira, 9 de agosto de 2011

IE8 Document Mode é Sticky !

Mais uma "feature" do IE8!
Se tivermos uma página simples, que abrimos em dois tabs, mas no primeiro tab definimos o URL como 'localhost' e o outro tab com o URL com o nome da máquina propriamente dito ("wheat", no exemplo).

Vamos constatar que o IE8, vai fazer o 'render' da página com margin e offset distintos, para a tag BODY.

A página está definida com o seguinte DOCTYPE:
<!-- DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" -->

Após mais alguns testes, acabei por descobrir que o problema não era do URL, mas sim devido ao facto de ter reutilizado um tab (alterando o seu URL), que conteve anteriormente uma página que forçou o modo de compatibilidade 'IE7' no IE8, com o seguinte meta dado no head !

<meta http-equiv="X-UA-Compatible" content="IE=8"/>

Resumindo e concluindo, o modo de compatibilidade aparentemente é uma propriedade do tab, e que não muda com a alteração do endereço (URL), como devia.

Isto implica que uma página que faça um render correcto, seguindo os standards, pode ficar completamente desfigurada no IE, se o tab tiver sido usado para aceder a outra página previamente, que tenha forçado o modo de compatibilidade do IE.






sexta-feira, 22 de julho de 2011

IE8 não gera evento form submit, em certas condições

Ultimamente, tenho andado a dançar o fandango com o IE8, ao fazer um 'port' de uma aplicação IE6 para IE8.

Infelizmente os bugs são mais que muitos: James Hopkins IE8 Bugs e Gérald Talbot's IE8 Bugs chegam para ter uma ideia dos problemas que se tem pela frente, já para não falar nos modos de (in)compatibilidade, que o bicho trás para o IE7.
Estranho é que alguns anos após o lançamento do IE8, a grande maioria dos problemas continua por resolver.

Mas voltando ao que interessa, o IE8 tem outro BUG ainda não documentado que consiste na falha em gerar um evento de 'submit' num form, em certas condições.

Se tivermos o seguinte código, o IE8 gera o evento 'submit' correctamente:
<form action="login">
<label for="user">User</label>
<input id="user" name="user" type="text" value="" />
<br/>
<label for="pass">Pass</label>
<input id="pass" name="pass" type="password" value="" />
<br/>
<input type="submit" value="Submit" />
</form>


Mas se quisermos adicionar um botão adicional, para por exemplo limpar o form (exemplo simplificado), o evento já não é despoletado.
NOTA: A implementação da funcionalidade em 'javascript' não é mostrada.

<form action="login">
<label for="user">User</label>
<input id="user" name="user" type="text" value="" />
<br/>
<label for="pass">Pass</label>
<input id="pass" name="pass" type="password" value="" />
<br/>
<input id="iClear" type="button" value="limpar" />
<input id="iSubmit" type="submit" value="Submit" />
</form>


E isto acontece apenas e somente, porque o IE8 não gosta que exista nenhum INPUT do tipo 'button', antes de um INPUT do tipo 'submit'. Isto é. aparentemente o IE8 procura o primeiro botão disponível e activa-o, mas se não fôr um botão do tipo 'submit', o form não é submetido, pois activa o botão errado.

A solução passa por ter o INPUT com o type='submit' aparecer em primeiro lugar no HTML.

<form action="login">
<label for="user">User</label>
<input id="user" name="user" type="text" value="" />
<br/>
<label for="pass">Pass</label>
<input id="pass" name="pass" type="password" value="" />
<br/>
<input id="iSubmit" type="submit" value="Submit" />
<input id="iClear" type="button" value="limpar" />
</form>


Se não gostarem do botão à esquerda, até por questões de usabilidade, podem sempre posicionar os botões por css com um float:right, que na pratica vos inverte a ordem relativamente a existente no HTML.