DIY – slideshow em jQuery

Faça você mesmo um slideshow em jQuery

Neste artigo vamos descobrir que não é necessário ir atrás de plugins toda vez que precisamos fazer algo em jQuery. A biblioteca tem muitas ferramentas e quando a tarefa é simples é mais rápido fazer você mesmo (DIY) do que procurar plugins por aí.

Por exemplo, outro dia eu precisava que um conteúdo fosse trocado por outro quando o user clicasse em “próximo”, alguns chamam de slideshow, outros de apresentação, tem muitos plugins por aí, que fazem todo tipo de coisa com todo tipo de animação, mil tipos de piruetas psicodélicas…

Até encontrar um que fizesse o necessário e sem bugs e fácil de usar demoraria um pouco, e para piorar o sistema em que eu estava mexendo não permitia incluir outros arquivos javascripts e tinha pouco tempo para entregar. Muitas vezes a gente perde um tempão procurando plugins e no final nenhum dos 15 encontrados servem, esse parecia ser o caso, os plugins eram bem diferentes um do outro. Então resolvi fazer eu mesmo.

zero: html e css

Este será o html usado neste exemplo, todos os slides estão em uma lista e aparecem um abaixo do outro:







  • 1
  • 2
  • 3
  • 4
  • 5




Demo zero

Um: javascript inicial

A ideia é pegar o html, esconder os slides e mostrar o primeiro.

Então adicionar um listener em cada botão, ao clicar o slide ativo é escondido substituído pelo próximo.

Mais uma linhazinha para quando chegar ao último voltar ao primeiro.

Em 17 linhas (descontando os comentários) já está montado um slideshow funcional:




Demo um

Dois: animação

Tá, funcionou, mas ficou sem graça, os slides trocam automaticamente sem efeito nenhum.

Vamos trocar o show() e hide() por um animate().


//ao clicar mostra o proximo slide
$('#slideproximo').click(function(){
//esconde o slide atual
$slideativo.animate({
"width": "toggle", "opacity": "toggle"
}, "slow", function() {//com callback
//
//procura o proximo
$slideativo = $slideshow.find("li.slideatual").next();
if(!$slideativo.size()) $slideativo = $slideshow.find("li.slide").first();//volta ao primeiro

//remove o marcador do slide anterior
$slideshow.find("li.slideatual").removeClass("slideatual");
//coloca o marcador e mostra
$slideativo.addClass("slideatual").animate({
"width": "toggle", "opacity": "toggle"
}, "slow");
});
});

//ao clicar mostra o slide anterior
$('#slideanterior').click(function(){
$slideativo.animate({
"width": "toggle", "opacity": "toggle"
}, "slow");//sem callback

$slideativo = $slideshow.find("li.slideatual").prev();
if(!$slideativo.size()) $slideativo = $slideshow.find("li.slide").last();//volta ao ultimo
$slideshow.find("li.slideatual").removeClass("slideatual");
$slideativo.addClass("slideatual").animate({
"width": "toggle", "opacity": "toggle"
}, "slow");
});

Demo dois

Repare que a animação de recolher usa um callback para começar a mostrar o outro slide só depois que o primeiro já terminou de recolher.

Mas ainda está meio estranha, tanto a animação “anterior” quanto “próxima” estão iguais, seria melhor que fossem diferentes.

Três: um pra cada lado

Para animar dqa esquerda para a direita primeiro o elemento precisa estar à esquerda $slideativo.show().css(“left”, $slideativo.outerWidth()*-1).css(‘opacity’, ‘0’);. Vários truques se escondem nessa linha:

outerWidth() serve para determinar o tamanho do slide

css(“left”, $slideativo.outerWidth()*-1) *-1 para colocar o slide à esquerda

show(), mas só funciona se o elemento estiver com “show”

css(‘opacity’, ‘0’) está com “show” mas ainda não deve aparecer.


$slideativo = $slideshow.find("li.slide").first().addClass('slideatual').css("left","0").show();

//ao clicar mostra o proximo slide
$('#slideproximo').click(function(){
//esconde o slide atual para a direita
$slideativo.animate({
"left": "+="+$slideativo.outerWidth(), "opacity": "0"
}, "slow", function() {//callback
//procura o proximo
$slideativo = $slideshow.find("li.slideatual").next();
if(!$slideativo.size()) $slideativo = $slideshow.find("li.slide").first();//volta ao primeiro

//remove o marcador do slide anterior
$slideshow.find("li.slideatual").removeClass("slideatual");

//posiciona na esquerda
$slideativo.show().css("left", $slideativo.outerWidth()*-1).css('opacity', '0');
//coloca o marcador e mostra
$slideativo.addClass("slideatual").animate({
"left": "0", "opacity": "1"
}, "slow");
});
});

//ao clicar mostra o slide anterior
$('#slideanterior').click(function(){
//esconde o slide atual para a esquerda
$slideativo.animate({
"left": "-="+$slideativo.outerWidth(), "opacity": "0"
}, "slow");
//procura o proximo
$slideativo = $slideshow.find("li.slideatual").prev();
if(!$slideativo.size()) $slideativo = $slideshow.find("li.slide").last();//volta ao ultimo

//remove o marcador do slide anterior
$slideshow.find("li.slideatual").removeClass("slideatual");

//posiciona na direita
$slideativo.show().css("left", $slideativo.outerWidth()).css('opacity', '0');
//coloca o marcador e mostra
$slideativo.addClass("slideatual").animate({
"left": "0", "opacity": "1"
}, "slow");
});

Repare que em uma está usando callback e na outra não, dessa maneira uma espera desaparecer para mostrar enquanto na outra os slides correm grudados, fica à escolha do freguês, veja a demo três.

Foi necessário também adicionar um .css("left","0") para posicionar corretamente os slides.

O css também teve que mudar um pouco:


#slides{
list-style-type: none;
width: 200px;
overflow: hidden;
}
.slide{
width: 200px;
height: 200px;
border: 1px solid #000;
left: -200px;
position: absolute;
}

Pronto, agora a animação é diferente, ao clicar em “anterior” os slides correm para a esquerda e em “próximo” os slides correm para a direita.

Demo Três

Quatro: Plugin

Beleza, agora se quiser mesmo fazer um plugin fica fácil, esse DIY não é sobre fazer plugin então vou economizar e usar o starter, um gerador de código que gera um template para plugins jQuery.

O código então fica assim (jquery.slideshow.js) (um pouco maior que as 17 linhas iniciais):


(function ($) {
//http://starter.pixelgraphics.us/
$.slideshow = function (el, options) {
// To avoid scope issues, use 'base' instead of 'this'
// to reference this class from internal events and functions.
var base = this;
// Access to jQuery and DOM versions of element
base.$el = $(el);
base.el = el;
// Add a reverse reference to the DOM object
base.$el.data("slideshow", base);

base.init = function(){
//junta as opcoes default com as passadas na chamada do plugin
base.options = $.extend({},$.slideshow.defaultOptions, options);

//um nome mais pratico para base.$el
$slideshow = base.$el;
//inicialmente esconde os slides
$slideshow.find("li.slide").hide();
//encontra o prmeiro slide e ativa-o
$slideativo = $slideshow.find("li.slide").first().addClass('slideatual').css("left","0").show();

base.proximo();
base.anterior();
};

base.proximo = function(paramaters){
//ao clicar mostra o proximo slide
$('#slideproximo').click(function(){
//esconde o slide atual para a direita
$slideativo.animate({
"left": "+="+$slideativo.outerWidth(),
"opacity": "0"
}, "slow");
//procura o proximo
$slideativo = $slideshow.find("li.slideatual").next();
if(!$slideativo.size()) $slideativo = $slideshow.find("li.slide").first();//volta ao primeiro

//remove o marcador do slide anterior
$slideshow.find("li.slideatual").removeClass("slideatual");

//posiciona na esquerda
$slideativo.show().css("left", $slideativo.outerWidth()*-1).css('opacity', '0');
//coloca o marcador e mostra
$slideativo.addClass("slideatual").animate({
"left": "0",
"opacity": "1"
}, "slow");
});
};

base.anterior = function(paramaters){
//ao clicar mostra o slide anterior
$('#slideanterior').click(function(){
//esconde o slide atual para a esquerda
$slideativo.animate({
"left": "-="+$slideativo.outerWidth(),
"opacity": "0"
}, "slow");
//procura o proximo
$slideativo = $slideshow.find("li.slideatual").prev();
if(!$slideativo.size()) $slideativo = $slideshow.find("li.slide").last();//volta ao ultimo

//remove o marcador do slide anterior
$slideshow.find("li.slideatual").removeClass("slideatual");

//posiciona na direita
$slideativo.show().css("left", $slideativo.outerWidth()).css('opacity', '0');
//coloca o marcador e mostra
$slideativo.addClass("slideatual").animate({
"left": "0",
"opacity": "1"
}, "slow");
});
};

// Run initializer
base.init();
};

$.slideshow.defaultOptions = {
//colocar aqui opcoes default
};

$.fn.slideshow = function(options){
return this.each(function () {
(new $.slideshow(this, options));
});
};
})(jQuery);

E para chamar o plugin basta incluir o script acima e “$(‘#slideshow’).slideshow();”




Demo quatro

No total demorou 1 hora para chegar na etapa 3, acho que demoraria mais ou menos a mesma coisa para encontrar um plugin que fizesse algo parecido, mas também poderia gastar esse tempo todo e não encontrar nenhum adequado.

Você já passou por isso também? Deixe um comentário.

PS: este post foi feito em html5, confira o código na demo principal

Também no github: https://github.com/codexico/diy-slideshow-jQuery


Publicado

em

por

Comentários

5 respostas para “DIY – slideshow em jQuery”

  1. Avatar de Aviso
    Aviso

    As demos não estão funcionando…

    1. Avatar de codexico

      Puxa, obrigado pelo aviso, os links estavam relativos, aí apareciam na home do blog mas não na interna, já arrumei, valeu!

  2. Avatar de Wilson
    Wilson

    Como faz um auto play e com stop simples ?

  3. Avatar de E. NETO
    E. NETO

    Pessoal, peço desculpas caso esteja sendo ignorante, mas onde fica o ‘”else” dessa parte:
    if(!$slideativo.size()) $slideativo = $(‘#slides’).find(“li”).first();

    ou melhor, porque não é necessário o “else” nesse caso?

  4. Avatar de Emerson Thompson
    Emerson Thompson

    E para ele ficar mudando sozinho, como faço? Já tentei adicionar um setimeout mas não rolou 🙁

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *