O mercado de e-commerce não para de crescer e este crescimento vem acompanhando de diversas novidades e melhorias nas interfaces das lojas virtuais. Uma delas é opção de arrastar e soltar produtos no carrinho de compras e é isso que você aprende neste artigo.
Se você comprou alguma coisa recentemente no Submarino deve ter notado uma nova opção na interface do site: agora é possível arrastar os produtos exibidos na página para o seu carrinho, que fica exibido de forma permanente no topo do site.
De uma forma simples, vou tentar mostrar pra vocês como implementar uma solução parecida utilizando jQuery e sua biblioteca para interfaces, a jQuery UI – é nela que encontramos os plugins draggable() e droppable(), responsáveis, como os nomes sugerem, por toda nossa operação de arrastar e soltar produtos.
Também veremos um pouco sobre o vasto universo de animações com jQuery através do método animate(). Diferente do Submarino, onde a barra superior é um novo elemento e não o próprio carrinho original, a nossa irá acompanhar de forma fluida o movimento do usuário na página.
Estrutura básica
Vamos começar com um pouco de HTML/CSS para apresentar nossa loja. A página terá os seguintes elementos:
- Barra localizada no topo (#carrinho-top) – essa barra, no carregamento inicial, estará relativa ao corpo do site. Assim que o usuário mover o mouse abaixo da metade da altura da barra, ela será “fixada” e acompanhará a navegação.
- Box do mini-carrinho (#carrinho-container) – ficará dentro da barra no topo e é a área onde o usuário pode “soltar” os produtos.
- Lista de produtos (#produtos) – a listagem de produtos, contendo os elementos que podem ser arrastados para o carrinho.
-
<div>
-
<div>
-
<p>Arraste produtos para esta área</p>
-
</div>
-
<div>
-
<ul>
-
<li class=”adicione”>Arraste produtos para esta área</li>
-
</ul>
-
</div>
-
</div>
-
…
-
<ul>
-
<li class=”produto-dd”><h3>Livro 1</h3><p><img src=’_img/twa.jpg’ width=’75’ height=’90’ /></p><p class=’preco-de’>De: R$31,00</p><p class=’preco-por’>Por: R$13,00</p></li>
-
…
-
</ul>
-
div#carrinho-top{background-color:#C92D21;width:960px;color:#fff;border-bottom:1px dashed #fff;opacity:.8;position:relative;}
-
div#carrinho-info{padding:10px;}
-
div#carrinho-container{height:240px;position:absolute;width:240px;background-color:#fff;border:2px solid #c92d21;display:none;}
-
div#carrinho-container ul{overflow:auto;height:200px;list-style:none;margin:10px;}
-
div#carrinho-container ul li{color:#333;font-size:12px;border-bottom:1px dotted #ccc;text-align:center;margin:10px;}
-
ul#produtos li{float:left;background-color:#fff;-moz-box-shadow:5px 5px 5px #ccc;-webkit-box-shadow:5px 5px 5px #ccc;box-shadow:5px 5px 5px #ccc;width:270px;text-align:center;margin:15px;padding:10px;}
Animando a barra superior
O primeiro passo da nossa implementação é fazer com que a barra superior acompanhe os movimentos do usuário, fazendo com que a área de drop dos produtos fique sempre visível. Para tornar isso possível associaremos uma função ao evento scroll da janela (window).
Toda vez que a a distância do scroll para o topo for maior do que a metade da altura da barra, o CSS será alterado para que a barra fique sempre visível e uma leve animação levará a barra para onde for o scroll.
-
// associando uma função ao evento scroll da janela
-
$(window).scroll(function(){
-
// valor do scroll – distância entre a barrinha menor e o início do scroll
-
var wtop = $(this).scrollTop();
-
// objeto da barra superior
-
var carrinho = $(‘#carrinho-top’);
-
// objeto container do site
-
var container = $(‘#container’);
-
// altura do carrinho
-
var cheight = $(carrinho).height();
-
// distância do scroll é maior do que a altura da barra / 2 ?
-
if( wtop > ( cheight / 2 ) )
-
{
-
// adiciona uma margem ao container para evitar quebra do lay-out
-
$(container).css(‘margin-top’, cheight+‘px’);
-
// transforma a position da barra em absolute
-
$(carrinho)
-
.css({
-
position: ‘absolute’
-
})
-
// anima utilizando a propriedade marginTop, com velocidade de 100ms
-
.animate({
-
marginTop: ( wtop – cheight ) + ‘px’
-
}, 100);
-
}
-
});
O funcionamento básico do método animate() segue o formato acima. O primeiro parâmetro é composto por um ou vários atributos CSS que farão a animação do elemento. No nosso caso, a barra será animada do valor original da sua margem superior até a especificada na função (a distância do scroll subtraída da altura da barra). Já o segundo parâmetro recebe um valor em milissegundos para efetuar a transição.
Precisamos agora de uma outra condição: quando o usuário voltar para o topo da página, nossa barra precisa recuperar o estado inicial, “fixado” no corpo:
-
// distância do scroll é menor do que a metade da altura da barra
-
else
-
{
-
$(container).css(‘margin-top’, 0);
-
$(carrinho)
-
.stop(true, true)
-
.css({
-
position: ‘relative’,
-
marginTop: 0
-
});
-
}
Definindo as áreas de drag and drop
Utilizando a biblioteca jQuery UI vamos definir os elementos que podem ser arrastados (qualquer li dentro da lista #produtos) e a área que vai recebê-los, no nosso caso o div #carrinho-container.
-
$(‘#produtos li’).draggable({
-
helper: ‘clone’,
-
start: function()
-
{
-
$(‘#carrinho-container’).show();
-
}
-
});
Os produtos, que podem ser arrastados, recebem o método draggable. Já ao box do carrinho é aplicado o método droppable. A chamada dos ítens recebe apenas o parâmetro helper e o evento start. O parâmetro helper pode receber os valores ‘original’, ‘clone’ ou uma função. Utilizaremos ‘clone’ que, como o nome sugere, clona o elemento original na ação de arrastar.
Já evento start acontece assim que o elemento começa a ser arrastado. Quando um produto sofre a ação de arrastar, precisamos exibir o carrinho, que é nossa área de drop.
-
$(‘#carrinho-produtos’).droppable({
-
hoverClass: ‘ui-state-hover’,
-
drop: function( event, ui )
-
{
-
// remove a marcação “arraste produtos para esta área”
-
$(this).find(‘.adicione’).remove();
-
// busca o ID do produto no campo hidden
-
var cod = ui.draggable.find(‘.produto-id’).val();
-
// verifica se o produto existe
-
if( $(this).find(‘#clone-‘+cod).length == 0 )
-
{
-
// adiciona o elemento li à lista de produtos do carrinho
-
$(‘<li></li>’).html(ui.draggable.html()).prependTo( this );
-
// animação para indicar que o produto foi adicionado
-
$(this).find(‘li:first’).slideDown();
-
// atualiza total de produtos do carrinho
-
var total_produtos = $(this).find(‘li’).length;
-
$(‘#carrinho-info’).html(‘<p>’ + total_produtos + ‘ produto’ + ( total_produtos > 1 ? ‘s’ : ” ) + ‘</p>’ );
-
}
-
}
-
});
No método droppable utilizaremos também um parâmetro e um evento. O parâmetro é o hoverClass, que especifica uma classe que será aplicada a àrea de drop quando um ítem estiver sendo arrastado (vamos utilizar o padrão da jQuery UI). E o evento drop é acionado toda vez que um elemento for “solto” no carrinho. Nossa função primeiro verifica se o produto já existe no carrinho. Caso não exista, cria um novo elemento li na lista com os dados do produto.
Para uma lista completa dos parâmetros e eventos visite jqueryui.com/demos/draggable e jqueryui.com/demos/droppable
Melhorando a exibição do carrinho
O código mostrado até agora tem um problema básico. Toda vez que o produto é adicionado o carrinho “some”. Seria legal que ele ficasse visível por uma certa quantidade detempo e só depois de um período de inatividade fosse escondido. Para isso vamos implementar um timer global na variável timerCarrinho.
Toda vez que o mouse estiver sobre o carrinho o timer é zerado. E, quando o mouse deixar a área, depois de 5 segundos, o carrinho é escondido.
-
var timerCarrinho = ”;
-
$(‘#produtos li’).draggable({
-
helper: ‘clone’,
-
start: function()
-
{
-
clearTimeout( timerCarrinho );
-
$(‘#carrinho-container’).show();
-
}
-
});
-
$(‘#carrinho-container’).mouseenter(function(){
-
clearTimeout( timerCarrinho );
-
});
-
$(‘#carrinho-container’).mouseleave(function(){
-
var carrinho = $(this);
-
timerCarrinho = setTimeout( function(){
-
$(carrinho).slideUp();
-
}, 5000 );
-
});
Dever de casa
Essa é uma versão básica de um carrinho drag and drop que pode sofrer diversas melhorias. Segue abaixo uma lista de implementações e funcionalidades novas pra vocês praticarem um pouco:
- Remover animação da barra, fazendo todo o posicionamento via CSS;
- Ao adicionar um produto que já exista no carrinho, aumentar a quantidade ao invés de ignorar;
- Adicionar funcionalidade para excluir produtos do carrinho;
- Salvar em cookie o carrinho do usuário, ou via AJAX, ou com o plugin de cookies do jQuery.
Por Davi Ferreira
Fonte: Tableless