Pesquisa de site

javascript - animando addClass/removeClass com jQuery


Estou usando jQuery e jQuery-ui e quero animar vários atributos em vários objetos.

Para explicar o problema aqui, simplifiquei para uma div que muda de azul para vermelho quando o usuário passa o mouse sobre ela.

Posso obter o comportamento que quero ao usar animate(), no entanto, ao fazer isso, os estilos que estou animando precisam estar no código da animação e, portanto, estão separados da minha folha de estilos. (veja Exemplo 1)

Uma alternativa é usar addClass() e removeClass(), mas não consegui recriar o comportamento exato que posso obter com animate(). (veja Exemplo 2)


Exemplo 1

Vamos dar uma olhada no código que eu tenho com animate():

$('#someDiv')
  .mouseover(function(){
    $(this).stop().animate( {backgroundColor:'blue'}, {duration:500});
  })
  .mouseout(function(){
    $(this).stop().animate( {backgroundColor:'red'}, {duration:500});
  });

ele exibe todos os comportamentos que estou procurando:

  1. Anima suavemente entre vermelho e azul.
  2. Sem animação de 'overqueue' quando o usuário move o mouse rapidamente para dentro e para fora do div.
  3. Se o usuário mover o mouse para fora/para dentro enquanto a animação ainda está em execução, ela suaviza corretamente entre o estado 'meio caminho' atual e o novo estado 'meta'.

Mas como as alterações de estilo são definidas em animate(), eu tenho que alterar os valores de estilo lá, e não posso apenas apontar para a minha folha de estilos. Esse 'fragmentamento' de onde os estilos são definidos me incomoda.


Exemplo 2

Aqui está minha melhor tentativa atual usando addClass() e removeClass (observe que para a animação funcionar você precisa do jQuery-ui):

//assume classes 'red' and 'blue' are defined

$('#someDiv')
  .addClass('blue')
  .mouseover(function(){
    $(this).stop(true,false).removeAttr('style').addClass('red', {duration:500});
  })
  .mouseout(function(){
    $(this).stop(true,false).removeAttr('style').removeClass('red', {duration:500});
  });

Isto exibe tanto as propriedades 1. quanto 2. dos meus requisitos originais, porém, 3 não funciona.

Eu entendo o motivo disso:

Ao animar addClass() e removeClass(), o jQuery adiciona um estilo temporário ao elemento e, em seguida, incrementa os valores apropriados até que alcancem os valores da classe fornecida, e somente então ele adiciona/remove a classe.

Por causa disso, eu tenho que remover o atributo style, caso contrário, se a animação for interrompida no meio, o atributo style permaneceria e sobrescreveria permanentemente quaisquer valores de classe, já que atributos style em uma tag têm maior importância do que estilos de classe.

No entanto, quando a animação está pela metade, ela ainda não adicionou a nova classe. Então, com essa solução, a cor pula para a cor anterior quando o usuário move o mouse antes que a animação seja concluída.


O que eu quero idealmente é poder fazer algo assim:

$('#someDiv')
  .mouseover(function(){
    $(this).stop().animate( getClassContent('blue'), {duration:500});
  })
  .mouseout(function(){
    $(this).stop().animate( getClassContent('red'), {duration:500});
  });

Onde getClassContent apenas retornaria o conteúdo da classe fornecida. O ponto chave é que, dessa forma, eu não preciso espalhar minhas definições de estilo por toda parte, mas posso mantê-las em classes na minha folha de estilo.

Resposta #1

Já que você não está preocupado com o IE, por que não usar apenas transições CSS para fornecer a animação e jQuery para mudar as classes. Exemplo ao vivo: http://jsfiddle.net/tw16/JfK6N/

#someDiv{
    -webkit-transition: all 0.5s ease;
    -moz-transition: all 0.5s ease;
    -o-transition: all 0.5s ease;
    transition: all 0.5s ease;
}

Resposta #2

Outra solução (mas requer jQueryUI como apontado por Richard Neil Ilagan nos comentários) :-

addClass, removeClass e toggleClass também aceitam um segundo argumento; a duração do tempo para ir de um estado para o outro.

$(this).addClass('abc',1000);

Veja jsfiddle:- http://jsfiddle.net/6hvZT/1/

Resposta #3

Você poderia usar o switchClass do jQuery UI, Aqui está um exemplo:

$( "selector" ).switchClass( "oldClass", "newClass", 1000, "easeInOutQuad" );

Ou veja este jsfiddle.

Resposta #4

Você só precisa do jQuery UI effects-core (13KB), para habilitar a duração da adição (assim como Omar Tariq apontou)

Artigos relacionados