11540 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous;

Voilà je deviens chèvre avec la fonction .animate().
Je suis en train de réaliser un slider responsive (j'en suis qu'au début hein ^^) et voilà mon problème :
Il y a des zones sensibles sur les bords pour aller au slide suivant ou précédent.
Pour le suivant pas de soucis.
Mais pour le précédent.... le slide demandé se positionne bien mais... .animate() ne veut pas fonctionner.

Je vous mets un lien pour vous faire une idée :
http://laugau.com/misc/laugau-slider/

Il faut juste que ma div #slide_x qui est positionnée à "margin-left : -z px" s'anime en retournant à "margin-left : 0px"...

Voici le code ou on peux voir deux syntaxes identique mais donc, la première ne fonctionne pas :


$("#"+newSlideId).show().css({"margin-left" : (-w)});
$("#"+newSlideId).animate({"margin-left" : "0px"});
$("#truc").show().css({"margin-left" : (-w)});
$("#truc").animate({"margin-left" : "0px"});


On peut voir que sur le carré noir (div "#truc"), ça fonctionne pourtant très bien....
Si vous avez une idée merciiiii.... Je suis dessus depuis tout l'aprem...
<3
Regarde dans ton code à la la ligne 29:

currentSlideNb = parseInt(currentSlideId.split("_")[1]);

currentSlideId estundefined tu devrais regarder de ce côté là
Meric Soldavox, je me sens moins seul ! Smiley smile

Mais quand je mets une alerte dans à la ligne 30 (juste en dessous) avec un petit :
alert(currentSlideNb); ça m'affiche "1", puis "2", puis "3"... (tout va bien de ce coté là je pense).

Penses-tu que ça puisse influencer la fonction animate() ?

Un exemple de ce que j'ai et qui ne fonctionne pas :

- On clique sur le coté droit du slider pour faire défiler les slides... on s'arrette sur le "slide_3" (par exemple).
- Quand je clique sur le coté gauche du slider (pour revenir en arrière donc); J'ai bien ma div #slide_2 qui réapparaît dans l'overflow hidden (sur la gauche) de mon slide_3 grâce à une positionnement avec margin-left = (-w), ou w c'est la largeur de mon bloc principal.
- Jusqu' ici tout va bien.... sauf qu'il doit y avoir une animation pour animer le margin-left pour le faire revenir à 0... (chose qui fonctionne d'ailleurs très bien dans firebug quand on augmente manuellement le margin-left de #slide_2 pour qu'il atteigne 0)....

Je mets le code complet :

$(document).ready(function() {

	// Dynamic Stylisation
	var nbSlides = $("#laugauslider>#slides>.slide").length;
	var allSlidesWidth = 100*nbSlides;
	var oneSlideWidth = 100/nbSlides;
	$("#laugauslider>#slides").css({"width": allSlidesWidth+"%",});
	$("#laugauslider>#slides>.slide").css({"width": oneSlideWidth+"%",});
	
	// INIT :
	var currentSlideId = $("div.slide.current").attr("id");
	var currentSlideNb = parseInt(currentSlideId.split("_")[1]);

	$("#laugauslider #arrow-right").click(function () {
		nextSlide (1);
	});
	$("#laugauslider #arrow-left").click(function () {
		nextSlide (-1);
	});


	function nextSlide (s) { //s = step
		var w = $("#laugauslider").width();
		currentSlideId = $("div.slide.current").attr("id");
		currentSlideNb = parseInt(currentSlideId.split("_")[1]);
		var newSlideNb = parseInt(currentSlideNb+s);
		var newSlideId= "slide_" + newSlideNb;
		var oldSlideId = currentSlideId;

		if (s<0) {
			
			$("#"+newSlideId).show().css({"margin-left" : (-w)});
			$("#"+newSlideId).animate({"margin-left" : "0px"});
			$("#truc").show().css({"margin-left" : (-w)});
			$("#truc").animate({"margin-left" : "0px"});

		}if (s>0){
			$(".slide").css({"margin-left" : 0}).hide();
			$("#"+newSlideId).show();
			$("#"+oldSlideId).show();
			$("#"+oldSlideId).animate({"margin-left" : -w,},800).queue(function (){
				$(".slide").css({"margin-left" : 0}).hide();
				$("#"+newSlideId).show();
			});

		}if (s=0){
			return false;
		}
		$(".slide").removeClass("current");
		$("#"+newSlideId).addClass("current");
	};
}); //end document Ready.

Modifié par LauGau (05 Jan 2015 - 11:40)
J'ai trouvé une solution qui fonctionne mais que je ne comprends pas...
J'ai testé avec un ".stop()" et ça fonctionne... Voici le code :

$("#"+newSlideId).show().css({"margin-left" : (-w)}).stop();
$("#"+newSlideId).animate({"margin-left" : "0px"},800);


Le plus muystérieux reste que le ".stop()" fonctionne juste après un ".css()". qui au final n'est même pas une animation...(et en plus sur l'autre animation celle du carré noir, il n'y en a pas besoin...) Smiley eek

Si quelqu'un peut m'expliquer ce qui se passe... Je suis preneur... Parceque là.. Smiley biggol
Bonsoir LauGau,

La syntaxe que vous exploitez rend difficile la relecture et le debug de votre code Smiley sweatdrop .
Voici quelques petits points faciles à mettre en place qui vous faciliteront grandement votre développement :

A. Réduire la longueur des pointeurs
A la place de ceci...
$("#laugauslider>#slides>.slide");

...enregistrez une fois pour toute vos éléments et réexploitez les ensuite. Vous ferez moins d'appels sur le DOM et améliorerez les performances :
var $laugauslider = $("#laugauslider");
var $slides = $("#slides");
var $slide = $slides.find(">.slide");

De plus le pointeur #laugauslider>#slides n'est pas nécessaire. Un ID est censé être unique, donc utilisez directement #slides. S'il n'est pas unique, c'est que l'ID n'est pas pertinent.

B. Utilisez les data attributs
Petite astuce pour indexer des éléments. A la place de :
<div id="slide_1" class="slide" style="width: 20%;">
<div id="slide_2" class="slide" style="width: 20%;">
<div id="slide_3" class="slide" style="width: 20%;">
<!--...-->

...exploitez un data-index="..." :
<div data-index="1" class="slide" style="width: 20%;">
<div data-index="2" class="slide" style="width: 20%;">
<div data-index="3" class="slide" style="width: 20%;">
<!--...-->

Ainsi vous pourrez remplacer...
currentSlideNb = parseInt(currentSlideId.split("_")[1]);

...par
currentSlideNb = $("div.slide.current").attr("data-index");

Et si vous avez un slide particulier à pointer, vous n'aurez qu'à écrire :
var $mySlide = $("div.slide[data-index='" + index + "']");


C. ATTENTION A CECI
if (s=0){
    return false;
}

...vous attribuez la valeur 0 à s, ce qui s'avère être toujours false. Il vaut mieux un :
if (s === 0){
    return false;
}

... ou encore (pour les aficionados) une yoda condition :
if (0 === s){
    return false;
}
mais avec yoda, c'est une autre histoire Smiley murf

Sinon, quitte à utiliser jQuery, un http://bxslider.com/ ne vous intéresserait pas ?
Il est responsive, performant, utilise les transitions CSS3 et facile d'exploitation Smiley cligne ...
Modifié par Guiwint (05 Jan 2015 - 22:51)
Merci beaucoup pour ces 3 conseils Guiwint, tu as parfaitement raison.
Je pense me les faire tatouer sous peu ^^.

Par rapport à BX slider, je le trouve très bien... mais... je me dis qu'il y a plein d'options qui ne me serviront surement jamais. Après c'est sûr qu'un code mal optimisé comme le miens est surement pire ^^.

Mais le problème principal de ce slider, c'est qu'il ne propose pas le passage direct d'une image A à une image D, sans passer rapidement par la B et la C... Sur les exemples avec 3 images, ce n'est pas gênant mais si on à 8 images dans le slider, ça va être moche (6 images qui défillent à 3000 km/h. si de l'image une on clique sur la 8). A moins que je n'ai pas trouvé l'option...

C'est vrai que j'ai tendance à réinventer la roue... mais ça me fait un support pour apprendre (et il reste tellement à faire Smiley biggol )
En tous cas, un grand merci à toi. Smiley smile