Slideshow images et textes en pur javascript

Soyez le premier à donner votre avis sur cette source.

Vue 14 407 fois - Téléchargée 2 707 fois

Description

Bjr,
Voulant me frotter de plus prêt à javascript, j'ai codé un slideshow 'par recouvrement' (z-index).
On peut choisir la direction du recouvrement et l'emplacement du texte.
La vitesse de défilement des images et du texte sont réglables séparément.
La démo se trouve sur cette page: http://ansuzpeorth.perso.sfr.fr/slideshow.xml

Source / Exemple :


/* CSS (slideshow.css) */

/* 
--------------------------------------------------------------------------------
------------- slideshow CSS ----------------------------------------------------
--------------------------------------------------------------------------------

  • /
.slideshow-img { background-color: white; background-repeat: no-repeat; background-position: center; } .content-text { overflow:hidden; position:relative; color:black; /* You can change */ text-align:center; /* You can change */ padding:5px; /* You can change */ margin-left:20px; /* You can change */ margin-right:20px; /* You can change */ z-index:0; } .back-trans { z-index:-1; position:absolute; overflow:hidden; top:0px; bottom:0px; left:0px; right:0px; background-color:white; /* You can change color & opacity */ filter:alpha(opacity=70); opacity:0.7; } .pos-left { right: 9999px; } .pos-right { left: 9999px; } /* -------------------------------------------------------------------------------- ------------- player CSS ------------------------------------------------------- --------------------------------------------------------------------------------
  • /
.triangle { width:0; height:0; border:8px solid transparent; } .triangle-droit { border-left:8px solid #323536; } .triangle-gauche { border-right:8px solid #323536; } .triangle-play { border-left:12px solid green; float:left; cursor: pointer; } .container-double { cursor: pointer; position:relative; float:left; z-index:11; } .second-triangle-droit { position:absolute; left:8px; top:0px; } .second-triangle-gauche { position:absolute; right:8px; top:0px; } .lecteurSlideShow { position:relative; background-color:white; filter:alpha(opacity=70); opacity:0.7; overflow:auto; padding: 5px 0px 2px 8px; width:70px; z-index:10; } /* END CSS */ /* JAVASCRIPT (slideshow.js) */ /* ############################################################################ ## ## ## Copyright (C) 2012 AnsuzPeorth (ansuzpeorth AT gmail DOT com) ## ## ## ## This program is free software: you can redistribute it and/or modify ## ## it under the terms of the GNU General Public License as published by ## ## the Free Software Foundation, either version 3 of the License, or ## ## (at your option) any later version. ## ## ## ## This program is distributed in the hope that it will be useful, ## ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## ## GNU General Public License for more details. ## ## ## ## You should have received a copy of the GNU General Public License ## ## along with this program. If not, see <http://www.gnu.org/licenses/>. ## ## ## ############################################################################
  • /
function ClassSlideshow() { // ------------------------------------------------------------------------- // ---------------------- class variable ----------------------------------- // ------------------------------------------------------------------------- this.currentSlide = 0; this.flagSliding = true; var _self = this; // ------------------------------------------------------------------------- // ---------------------- utility ------------------------------------------ // ------------------------------------------------------------------------- this.returnType = function() { if(this.currentElement.textPosition == 'left') { var type = 'right'; } else{ var type = 'left'; } return type; } // ------------------------------------------------------------------------- // ---------------------- image animation ---------------------------------- // ------------------------------------------------------------------------- this.refreshOrderSlideList = function() { // enleve le premier div de la liste et ajoute un nouveau à la fin this.orderSlideListe[0].div.style.zIndex = -2; this.orderSlideListe.shift(); this.currentSlide += 1; if(this.currentSlide == this.slideshowImages.length) {this.currentSlide=0 }; this.currentElement = this.slideshowImages[this.currentSlide]; this.orderSlideListe[2] = this.currentElement; this.orderSlideListe[1].div.style.zIndex = 1; this.orderSlideListe[0].div.style.zIndex = 0; } this.refreshOrderSlideListInvert = function() { // tri de la liste inversée this.orderSlideListe[0] = this.orderSlideListe[1]; this.orderSlideListe[1] = this.orderSlideListe[2]; this.currentSlide -= 1; if(this.currentSlide == -1) {this.currentSlide = this.slideshowImages.length-1}; this.currentElement = this.slideshowImages[this.currentSlide]; this.orderSlideListe[2] = this.currentElement; this.orderSlideListe[1].div.style.zIndex = 1; this.orderSlideListe[0].div.style.zIndex = 0; } this.manageSlides = function(sens) { // @sens bool if(sens){ this.refreshOrderSlideListInvert(); }else { this.refreshOrderSlideList(); } this.currentElement.div.style.zIndex = 2; this.animateSlide(this.currentElement.sliding, this.currentElement.div, this.slideHeight, this.currentElement.animationPas, this.currentElement.animationProgress); } this.animateSlide = function(type, div, pos, pas, timing) { // @type top,bottom,left,right // @div the current div image // @pos the position in pixel // @pas the pas of progress // @timing the delay if(pos <= 0){ eval('div.style.'+type +' = "0px"'); this.launchTextAnimation(); } else { eval('div.style.'+type +' = "'+pos+'px"'); this.animateTimeout = window.setTimeout(function() { _self.animateSlide(type, div, pos-pas, pas, timing); },timing); } } // ------------------------------------------------------------------------- // ---------------------- texte animation ---------------------------------- // ------------------------------------------------------------------------- this.launchTextAnimation = function() { var div_text = this.currentElement.divText; var type = this.returnType(); div_text.style.cssFloat = this.currentElement.textPosition; div_text.style.top = this.currentElement.textTop+'px'; eval('div_text.style.'+type+' = "'+div_text.offsetWidth+'px"'); this.animateText( div_text, type, div_text.offsetWidth, this.currentElement.animationTextPas, this.currentElement.animationTextProgress); } this.animateText = function(div_text, type, pos, pas, timing) { // @type left,right // @div_text the current div text // @pos the position in pixel // @pas the pas of progress // @timing the delay if(pos <= 0) { eval('div_text.style.'+type+' = "0px"'); if(this.flagSliding) { this.animeTextTimeout = window.setTimeout(function(){ _self.hideDivText(div_text, type); }, this.slideChangeDelay); } }else { eval('div_text.style.'+type+' = "'+pos+'px"'); this.timeOutText = window.setTimeout(function(){ _self.animateText(div_text, type, pos-pas, pas, timing); }, timing); } } this.hideDivText = function(div, type) { // @type left,right // @div the current div text eval('div.style.'+type+' = "9999px"'); if(this.flagSliding) { this.manageSlides(); } } // ------------------------------------------------------------------------- // ---------------------- creation slideshow ------------------------------- // ------------------------------------------------------------------------- this.createSlideshow = function() { var divContainer = document.getElementById(this.slideContentDiv); divContainer.style.width = this.slideWidth+'px'; divContainer.style.height = this.slideHeight+'px'; divContainer.style.margin = 'auto'; divContainer.style.overflow = 'hidden'; divContainer.style.position = 'relative'; divContainer.setAttribute('onmouseover', this.name+'.mouseOverCb()'); divContainer.setAttribute('onmouseout', this.name+'.mouseOutCb()'); for(var i in this.slideshowImages) { var element = this.slideshowImages[i] var container = document.createElement('div'); container.style.width = this.slideWidth+'px'; container.style.height = this.slideHeight+'px'; container.style.zIndex = -2; container.style.position = 'absolute'; container.style.backgroundImage = 'url("'+element.url+'")'; container.className = 'slideshow-img'; var div_text = document.createElement('div'); div_text.className = 'content-text pos-'+element.textPosition; div_text.innerHTML = '<div class="back-trans"></div>'+element.text; container.appendChild(div_text); divContainer.appendChild(container); this.slideshowImages[i].div = container; this.slideshowImages[i].divText = div_text; } divContainer.appendChild(this.createPlayer()); // chargement de la liste de reference des slideimage.(3 necessaires,zIndex) this.orderSlideListe = [ this.slideshowImages[this.slideshowImages.length-2], this.slideshowImages[this.slideshowImages.length-1], this.slideshowImages[0], ]; this.currentElement = this.slideshowImages[0]; this.currentElement.div.style.zIndex = 2; this.launchTextAnimation(); } // ------------------------------------------------------------------------- // ---------------------- slideshow callbacks ------------------------------ // ------------------------------------------------------------------------- this.mouseOverCb = function() { this.lecteur.style.top = this.slideHeight - 22 +'px'; } this.mouseOutCb = function() { this.lecteur.style.top = this.slideHeight - 2 +'px'; } // ------------------------------------------------------------------------- // ---------------------- creation player ---------------------------------- // ------------------------------------------------------------------------- this.createPlayer = function() { this.lecteur = document.createElement('div'); this.lecteur.className = 'lecteurSlideShow'; this.lecteur.style.marginLeft = (this.slideWidth / 2) - 70 +'px'; this.lecteur.style.top = this.slideHeight - 2 +'px'; this.playButton = document.createElement('div'); this.playButton.className = 'triangle triangle-play'; this.playButton.setAttribute('onclick', this.name +'.playerPlayClickedCb(this)'); this.lecteur.appendChild(this.playButton); var contain_double = document.createElement('div'); contain_double.className = 'container-double'; var triangle = document.createElement('div'); triangle.className = 'triangle triangle-gauche'; contain_double.appendChild(triangle); var second_triangle = document.createElement('div'); second_triangle.className = 'triangle triangle-gauche second-triangle-gauche'; contain_double.appendChild(second_triangle); contain_double.setAttribute('onclick', this.name +'.playerPrecedentClickedCb()'); this.lecteur.appendChild(contain_double); var contain_double = document.createElement('div'); contain_double.className = 'container-double'; contain_double.style.left = '10px'; var triangle = document.createElement('div'); triangle.className = 'triangle triangle-droit'; contain_double.appendChild(triangle); var second_triangle = document.createElement('div'); second_triangle.className = 'triangle triangle-droit second-triangle-droit'; contain_double.appendChild(second_triangle); contain_double.setAttribute('onclick', this.name +'.playerSuivantClickedCb()'); this.lecteur.appendChild(contain_double); return this.lecteur; } // ------------------------------------------------------------------------- // ---------------------- player callbacks --------------------------------- // ------------------------------------------------------------------------- this.playerPlayClickedCb = function(div) { // @div the div of play button if(this.flagSliding) { window.clearTimeout(this.animeTextTimeout); window.clearTimeout(this.timeOutText); this.flagSliding = false; div.style.borderLeft = '12px solid red'; }else { this.flagSliding = true; div.style.borderLeft = '12px solid green'; this.hideDivText(this.currentElement.divText, this.returnType()); } } this.playerSuivantClickedCb = function(flag) { // @flag bool sens of sort window.clearTimeout(this.timeOutText); window.clearTimeout(this.animeTextTimeout); if(this.flagSliding) { this.playerPlayClickedCb(this.playButton); } this.hideDivText(this.currentElement.divText, this.returnType()); this.manageSlides(flag); } this.playerPrecedentClickedCb = function() { this.playerSuivantClickedCb(true) } } /* END JAVASCRIPT */ /* HTML (slideshow.html) */ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta content="text/html; charset=UTF-8" http-equiv="content-type"> <script src="slideshow.js" type="text/javascript"></script> <link href="slideshow.css" rel="stylesheet" type="text/css" /> <title>Ansuz Slideshow</title> <script type="text/javascript"> /* reference pour une image -------------------------------------------------------------------------------- { url:'visuel_1.jpg', sliding: 'top/bottom/left/right', text: 'Le texte', textPosition: 'left/right', textTop: '70', => position du texte par le haut en pixel animationPas:'10', => le nombre de pixel à chaque itérations, en pixel animationProgress:'50', => itération en ms animationTextPas:'5', => le nombre de pixel à chaque itérations, en pixel animationTextProgress:'5', => itération en ms } --------------------------------------------------------------------------------
  • /
var listeImages = [ { url:'visuel_1.jpg', sliding: 'top', text: 'Visitez nos cotes sauvages', textPosition: 'left', textTop: '70', animationPas:'10', animationProgress:'50', animationTextPas:'5', animationTextProgress:'5', }, { url:'visuel_2.jpg', sliding:'bottom', text:'Nos falaises remarquables', textPosition:'left', textTop:'20', animationPas:'10', animationProgress:'50', animationTextPas:'5', animationTextProgress:'5', }, { url:'visuel_3.jpg', sliding:'top', text:'Protégée du grand large', textPosition:'right', textTop:'100', animationPas:'10', animationProgress:'50', animationTextPas:'5', animationTextProgress:'5', }, { url:'visuel_4.jpg', sliding:'bottom', text:'Notre lagon de mer turquoise', textPosition:'left', textTop:'100', animationPas:'10', animationProgress:'50', animationTextPas:'5', animationTextProgress:'5', }, { url:'visuel_5.jpg', sliding:'top', text:'Sans oublier nos plages de sables fin<br>et nos filles dénudées !', textPosition:'right', textTop:'20', animationPas:'10', animationProgress:'50', animationTextPas:'5', animationTextProgress:'5', }, ]; var monSlideshow = new ClassSlideshow(); monSlideshow.slideshowImages = listeImages; monSlideshow.name = 'monSlideshow'; //indiquer nom de la var utiliser pour la class monSlideshow.slideHeight = 150; monSlideshow.slideWidth = 700; monSlideshow.slideChangeDelay = 3000; // 3 secondes entre chaque image monSlideshow.slideContentDiv = 'slideshow'; //la div contenant le slideshow if (window.attachEvent) { window.attachEvent("onload", monSlideshow.createSlideshow()); } else { window.onload = function() { monSlideshow.createSlideshow(); } } </script> </head> <body> <br> <div id="slideshow"> </div> </body></html> /* END HTML */

Conclusion :


Version actuelle: 3 (code ci-dessus version 1)
L'archive en PJ contient des images pour pouvoir tester de suite ;)
Je n'ai pas essayé sous IE (le player est en CSS, et les border transparent sous ie, je sais pas...!), si qql'un peut me donner un retour à ce sujet ?
Toutes critiques bienvenues, je ne suis pas expert en javascript (ni en autre choses d'ailleurs !)

Thx,

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Simple et bien dans l'ensemble
Bonjour et merci pour se slideshow. Logiquement je devrais l'installer sur mon site de cuisine. on va voir ce que ça donne. encor merci.
Problème d'affichage avec un menu déroulant en css.
Bonjour à tous, j'ai eu à personnaliser le script et il fonctionne bien chez moi (sous opera, Chrome, safari et mozilla, j'ai pas encore testé sous IE- je suis encore en chantier avec mon site). J'ai un problème avec mon menu déroulant qui est développé en CSS. les images du slideshow cache mon menu déroulant. Est-il techniquement possible de remédier à la situation? faire en sorte que le menu soit au premier plan par rapport au slideshow.
J'ai besoin d'aide s'il vous plait !!!!

/* ------------------ MENU PRINCIPAL --------------------*/

div#menu_bas a {
color:#FFFFFF; }

div#menu_bas ul {
list-style-type:none;
font-family:Verdana, Arial, Helvetica, sans-serif;
font-size:10px;
font-style:normal;
margin-bottom:0px;
margin-top:opx;
padding: 0px; margin:0px; background-color: #009; text-align:left;
display:block;
float:left;
}

div#menu_bas li {
list-style-type:none;
font-family:Verdana, Arial, Helvetica, sans-serif;
font-size:10px;
font-style:normal;
margin-left:0px;
margin-bottom:0px;
margin-top:0px;
background-color:#009;
display:block;
float:left;}

div#menu_bas li:hover { background-color:#009;}

div#menu_bas li.sousmenu:hover {background-color:#e5680e;}

/*rajout couleure de fond */
div#menu_bas li.sousmenu { background-color: #009;}

/* rajout pr pour flèche direction bas et couleur de fond*/
div#menu_bas li.plop { background-color:#009;}

/* une petite bordure en top*/
div#menu_bas ul li {
position:relative; list-style: none; float:left; border-top:0.1em solid; border-color:#FFF;}

div#menu_bas ul ul { position:absolute; display:none; width:auto;}
div#menu_bas li a {text-decoration: none; padding: 4px 0 4px; display:block;width:15.89em; margin:0px;}
div#menu_bas ul.niveau1 li.sousmenu:hover ul.niveau2 {display:block;}

/*div#menu ul.niveau2 li.sousmenu:hover ul.niveau3
div#menu ul.niveau3 {top:-1px; left: 135px;}

rajout de couleures de fond et de survol*/
div#menu ul.niveau3 li { background-color: #009;}
div#menu ul.niveau3 li:hover { background-color: #009;}
/* ---------------------- MON MENU DANS LE CODE HTML ----------------- */





* ["#"> ECPC

* Nos objectifs

* Nos valeurs

* Historique


* VOUS ÊTES...


* Particuliers

* Fontionnaires/Salariés

* Commerçants

* ONG/Associations

* Agriculteurs/Eleveurs

* PME/PMI




* SERVICES & PRODUITS


* Compte d´épargne


* Compte chèque particulier

* Compte bloqué

* Compte courant

* Bon de caisse

* Epargne mobile

* Transfert de fonds

* Change de devises




* NOTRE RESEAU

* Littoral

* Centre

* Ouest

* Nord Ouest

* Sud Ouest

* Adamaoua

* Nord

* Extrême Nord




* CARRIERE


* Nos métiers

* Comment postuler ?

* Formations




*











// peut aussi etre instancié dans une fonction onload,
// avec les inconvénients qui en découlent ...
monSlideshow.createSlideshow();
monSlideshow1.createSlideshow();
ansuzpeorth
Messages postés
4
Date d'inscription
jeudi 7 octobre 2010
Statut
Membre
Dernière intervention
23 avril 2012

Désolé pour le temps de réponse, j'étais pas mal occupé.

** Pour ton souci concernant plusieurs listes, c'est logique, ta variable est forcément en référence, puisqu'instanciée dans un objet. **
Des fois, je me demande à quoi je pense ... C'est le même objet, donc c'est normal que ca merdois.

** La solution pour moi est que tu ajoutes une méthode d'initialisation qui crée un objet dans ta classe, et non pas simplement une référence vers une variable. **
C'est ce que j'ai fait pour la version 3, mais le truc qui me gêne, c'est que l'objet est créé en double (car je dois le cloner). Donc si on embarque 5 slideshow différents, on aura 10 objets de liste d'images ... Par contre, ca a l'avantage de pouvoir utiliser la même liste pour plusieurs slideshow. Bon, c'est du pinaillage, car maintenant avec la RAM embarquée dans les nouveaux PC, on est pas à qqles octets pret !

** Le type qui te met un apostrophe dans le texte de l'image et tu as tout qui saute. **
Ahhh, le fameux utilisateur lambda ... J'ai ajouté une petite note à ce sujet dans le code HTML, ca devrait suffire je pense.

** tu pourras demander à l'utilisateur une syntaxe bien moins rude que l'instanciation de variables **
Hum, là je suis pas tout à fait de ton avis, je trouve bien plus galère de renseigner des argument simplement dans un string, que de devoir renseigner des 'variables' qui sont explicites (enfin, j'ai essayé qu'elles le soient ..). De plus, on peut indiquer jusqu'à 13 variables, certaines sont optionnelles, on a vite fait de s'y perdre ...
Mais ce n'est que mon avis, ca serait intéressant de faire un sondage auprès des utilisateurs lambda, ce qu'ils trouvent le plus clair.

** pourquoi ne mets-tu pas dans cette css des propriétés que tu redéclares pour chaque élément ? **
Ben je ne voulais pas trop charger le css, mais j'ai écouté tes conseils, j'utilise 100%, bien que webkit n'aime pas trop les % (et display: block ca fait pas).
Comme ça, le html généré sera moins lourd ...

En tout cas merci d'avoir passé du temps pour répondre, c'est avec les conseils de personnes plus expirementées qu'on apprends.
iguypouf
Messages postés
45
Date d'inscription
mercredi 27 octobre 2004
Statut
Membre
Dernière intervention
26 août 2009

Pas mal pas mal :)

Pour ton souci concernant plusieurs listes, c'est logique, ta variable est forcément en référence, puisqu'instanciée dans un objet.

La solution pour moi est que tu ajoutes une méthode d'initialisation qui crée un objet dans ta classe, et non pas simplement une référence vers une variable.

En plus d'éviter ton problème, j'y vois deux avantages majeurs :
1/ ta méthode pourra faire un contrôle de données (n'oublie pas que c'est l'utilisateur qui crée la liste d'images, et donc sans doute pas au fait des bonnes pratiques. Le type qui te met un apostrophe dans le texte de l'image et tu as tout qui saute.
2/ tu pourras demander à l'utilisateur une syntaxe bien moins rude que l'instanciation de variables (exemple, tu pourrais très bien demander de passer un array de ce type : "visuel_1.jpg;top;Visitez nos cotes ;left;70;10;50;5;5"

Du coup, au lieu de faire ça :
439.var monSlideshow = new ClassSlideshow();
440.monSlideshow.slideshowImages = listeImages;

tu fais ça :
439.var monSlideshow = new ClassSlideshow();
440.monSlideshow.initslideshowImages(listeImages);

De cette manière, tu instancies une variable locale grâce aux valeurs que tu vas caster et vérifier. Il n'y aura donc plus aucun souci de réécriture du contenu de listeImages.

Enfin, pour finir, quelques remarques pratiques :
for(var i in this.slideshowImages) {
246. var element = this.slideshowImages[i]
247. var container = document.createElement('div');
248. container.style.width = this.slideWidth+'px';
249. container.style.height = this.slideHeight+'px';
250. container.style.zIndex = -2;
251. container.style.position = 'absolute';
252. container.style.backgroundImage = 'url("'+element.url+'")';
253. container.className = 'slideshow-img';
254. var div_text = document.createElement('div');
255. div_text.className = 'content-text pos-'+element.textPosition;
256. div_text.innerHTML = '

'+element.text;
257. container.appendChild(div_text);
258. divContainer.appendChild(container);
259. this.slideshowImages[i].div = container;
260. this.slideshowImages[i].divText = div_text;
261. }

Puisque tu affectes à ton div la classe css slideshow-img, pourquoi ne mets-tu pas dans cette css des propriétés que tu redéclares pour chaque élément ?
Genre ça : container.style.position = 'absolute';, opéré à chaque itération, peut être remplacé par "position: absolute;", dans la déclaration de ta classe css. Pareil pour ton z-Index.

Si je lis bien, tes deux tailles sont les mêmes que l'élément qui les contient, tu peux donc oublier ça et déclarer un width et height de 100% dans ta classe css, voire même un display:block si je ne m'abuse.
Afficher les 12 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.