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.