11550 sujets

JavaScript, DOM et API Web HTML5

Salut a tous,

J'ai trouvé un petit "slider" JS tres simple pour faire defiler horizontalement des images une a une, et je voudrais integrer ca dans un "popup jQuery" (un <div> s'affichant au centre de l'ecran par un click, avec toute la page grisée derriere). Probleme: chacune de ces 2 fonctionnalités marche tres bien de leur coté, mais une fois combinées le slider ne marche plus. Et ... l'auteur du script n'assure plus de support technique.

Le slider tout seul : http://balthy.com/version%20NORMAL.html

Le code du slider :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<script src="jquery-1.2.6.min.js" type="text/javascript" charset="utf-8"></script>

	<style type="text/css">
		/* easySlider Stuff */
		#slider ul, #slider li{			margin:0; padding:0; list-style:none; }
		#slider, #slider li{ 			width:200px; height:100px; overflow:hidden; display: block;	}
		
		span#prevBtn{}
		span#nextBtn{}	
	</style>  
	
	<script language="JavaScript" type="text/javascript">
	
		/* Slider Stuff */
		(function($) {

		$.fn.easySlider = function(options){
		  
		// default configuration properties
		var defaults = {			
			prevId: 		'prevBtn',
			prevText: 		'Previous',
			nextId: 		'nextBtn',	
			nextText: 		'Next',
			controlsShow:	true,
			controlsBefore:	'',
			controlsAfter:	'',	
			controlsFade:	true,
			firstId: 		'firstBtn',
			firstText: 		'First',
			firstShow:		false,
			lastId: 		'lastBtn',	
			lastText: 		'Last',
			lastShow:		false,				
			vertical:		false,
			speed: 			800,
			auto:			true,
			pause:			2000,
			continuous:		false, 
			numeric: 		false,
			numericId: 		'controls'
		}; 
		
		var options = $.extend(defaults, options);  
				
		this.each(function() {  
			var obj = $(this); 				
			var s = $("li", obj).length;
			var w = $("li", obj).width(); 
			var h = $("li", obj).height(); 
			var clickable = true;
			obj.width(w); 
			obj.height(h); 
			obj.css("overflow","hidden");
			var ts = s-1;
			var t = 0;
			$("ul", obj).css('width',s*w);			
			
			if(options.continuous){
				$("ul", obj).prepend($("ul li:last-child", obj).clone().css("margin-left","-"+ w +"px"));
				$("ul", obj).append($("ul li:nth-child(2)", obj).clone());
				$("ul", obj).css('width',(s+1)*w);
			};				
			
			if(!options.vertical) $("li", obj).css('float','left');
								
			if(options.controlsShow){
				var html = options.controlsBefore;				
				if(options.numeric){
					html += '<ol id="'+ options.numericId +'"></ol>';
				} else {
					if(options.firstShow) html += '<span id="'+ options.firstId +'"><a href=\"javascript:void(0);\">'+ options.firstText +'</a></span>';
					html += ' <span id="'+ options.prevId +'"><a href=\"javascript:void(0);\">'+ options.prevText +'</a></span>';
					html += ' <span id="'+ options.nextId +'"><a href=\"javascript:void(0);\">'+ options.nextText +'</a></span>';
					if(options.lastShow) html += ' <span id="'+ options.lastId +'"><a href=\"javascript:void(0);\">'+ options.lastText +'</a></span>';				
				};
				
				html += options.controlsAfter;						
				$(obj).after(html);										
			};
			
			if(options.numeric){									
				for(var i=0;i<s;i++){						
					$(document.createElement("li"))
						.attr('id',options.numericId + (i+1))
						.html('<a rel='+ i +' href=\"javascript:void(0);\">'+ (i+1) +'</a>')
						.appendTo($("#"+ options.numericId))
						.click(function(){							
							animate($("a",$(this)).attr('rel'),true);
						}); 												
				};							
			} else {
				$("a","#"+options.nextId).click(function(){		
					animate("next",true);
				});
				$("a","#"+options.prevId).click(function(){		
					animate("prev",true);				
				});	
				$("a","#"+options.firstId).click(function(){		
					animate("first",true);
				});				
				$("a","#"+options.lastId).click(function(){		
					animate("last",true);				
				});				
			};
			
			function setCurrent(i){
				i = parseInt(i)+1;
				$("li", "#" + options.numericId).removeClass("current");
				$("li#" + options.numericId + i).addClass("current");
			};
			
			function adjust(){
				if(t>ts) t=0;		
				if(t<0) t=ts;	
				if(!options.vertical) {
					$("ul",obj).css("margin-left",(t*w*-1));
				} else {
					$("ul",obj).css("margin-left",(t*h*-1));
				}
				clickable = true;
				if(options.numeric) setCurrent(t);
			};
			
			function animate(dir,clicked){
				if (clickable){
					clickable = false;
					var ot = t;				
					switch(dir){
						case "next":
							t = (ot>=ts) ? (options.continuous ? t+1 : ts) : t+1;						
							break; 
						case "prev":
							t = (t<=0) ? (options.continuous ? t-1 : 0) : t-1;
							break; 
						case "first":
							t = 0;
							break; 
						case "last":
							t = ts;
							break; 
						default:
							t = dir;
							break; 
					};	
					var diff = Math.abs(ot-t);
					var speed = diff*options.speed;						
					if(!options.vertical) {
						p = (t*w*-1);
						$("ul",obj).animate(
							{ marginLeft: p }, 
							{ queue:false, duration:speed, complete:adjust }
						);				
					} else {
						p = (t*h*-1);
						$("ul",obj).animate(
							{ marginTop: p }, 
							{ queue:false, duration:speed, complete:adjust }
						);					
					};
					
					if(!options.continuous && options.controlsFade){					
						if(t==ts){
							$("a","#"+options.nextId).hide();
							$("a","#"+options.lastId).hide();
						} else {
							$("a","#"+options.nextId).show();
							$("a","#"+options.lastId).show();					
						};
						if(t==0){
							$("a","#"+options.prevId).hide();
							$("a","#"+options.firstId).hide();
						} else {
							$("a","#"+options.prevId).show();
							$("a","#"+options.firstId).show();
						};					
					};				
					
					if(clicked) clearTimeout(timeout);
					if(options.auto && dir=="next" && !clicked){;
						timeout = setTimeout(function(){
							animate("next",false);
						},diff*options.speed+options.pause);
					};
			
				};
				
			};
			// init
			var timeout;
			if(options.auto){;
				timeout = setTimeout(function(){
					animate("next",false);
				},options.pause);
			};		
			
			if(options.numeric) setCurrent(0);
		
			if(!options.continuous && options.controlsFade){					
				$("a","#"+options.prevId).hide();
				$("a","#"+options.firstId).hide();				
			};				
			
		});
		  
		};

		})(jQuery);

		



		/* jQuery Popup Stuff */
		function Show_Popup_tem(action, userid) {
			$('#popup').fadeIn(10);
			$('#window_tem').fadeIn(10);
		}
		function Close_Popup_tem() {
			$('#popup').fadeOut(100);
			$('#window_tem').fadeOut(100);
		}
	
		/* easySlider1.7 Stuff */
		$(document).ready(function () {
			$("#slider").easySlider();
		});
	</script>
</head>
		
<body>
	<div id="popup" style="display: none;"></div> 
		<a href="#" onclick="Close_Popup_tem();">close</a>
		<div id="slider">
			<ul>
				<li>content here...</li>
				<li>content here...</li>
				<li>content here...</li>
			</ul>
		</div>
</body>
</html>



Et le slider integré dans un popup jQuery simple : http://balthy.com/version POPUP.html

Code (le JS en include ici est le meme que celui "embedded" du premier cas) :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<script src="jquery-1.2.6.min.js" type="text/javascript" charset="utf-8"></script>
	<script src="easySlider1.7.js" type="text/javascript" charset="utf-8"></script>
	<style type="text/css">
		/* jQuery Popup Stuff */
		#popup {
			height: 100%;
			width: 100%;
			background: #000000;
			position: absolute;
			top: 0;
			-moz-opacity:0.75;
			-khtml-opacity: 0.75;
			opacity: 0.75;
			filter:alpha(opacity=75);
		}
		#window_tem {
			width: 340px;
			height: 240px;
			margin: -120px 0 0 -170px;
			padding: 0;
			border: 8px solid #353230;
			position: absolute;
			top: 50%;
			left: 50%;
			background: white ;
		}
	
		/* easySlider Stuff */
		#slider ul, #slider li{			margin:0; padding:0; list-style:none; }
		#slider, #slider li{ 			width:200px; height:100px; overflow:hidden; display: block;	}
		
		span#prevBtn{}
		span#nextBtn{}	
		
	</style>  
	
	<script language="JavaScript" type="text/javascript">
		/* jQuery Popup Stuff */
		function Show_Popup_tem(action, userid) {
			$('#popup').fadeIn(10);
			$('#window_tem').fadeIn(10);
		}
		function Close_Popup_tem() {
			$('#popup').fadeOut(100);
			$('#window_tem').fadeOut(100);
		}
	
		/* easySlider1.7 Stuff */
		$(document).ready(function () {
			$("#slider").easySlider();
		});
	</script>
</head>
		
<body>
	<div id="popup" style="display: none;"></div>
	<div id="window_tem" style="display: none;">
		<a href="#" onclick="Close_Popup_tem();">close</a>
		<div id="slider">
		<ul>
			<li>content here...</li>
			<li>content here...</li>
			<li>content here...</li>
		</ul>
		</div>
	</div>
	<a href="#" onClick="Show_Popup_tem();" >Popup	</a>
</body>
</html>


Hum vu la taille de ce post j'imagine que pas grand monde prendra le temps de tout lire, mais sait-on jamais! Quelqu'un pourra peut etre reperer la cause du probleme, qui est le suivant : le contenu du slider n'apparait pas, apparemment parce qu'il est contenu dans un conteneur dont la largeur et la longueur sont, sans que je comprenne pourquoi, egales a 0...
Modifié par apericube (07 Aug 2009 - 20:01)
Je réagis sur cette dernière phrase en disant que c'est parce que ce dernier est en display none (effet d'un fadeOut) et par conséquent hors du flux. Conclusion, pas de dimension. L'astuce est de mettre ton conteneur hors du viewport, genre à -10000px left/top.

Si ce n'est pas ça je reviendrai en détail sur ton post qui est effectivement bien long Smiley lol

[Edit] ortografe
Modifié par Ze Nenex (07 Aug 2009 - 20:03)
HMM je comprend pas ce que tu dis Branleur de l'Espace lol! Tu parles de remplacer position: absolute par position: relative et mettre genre un top: -9999px dans

#popup {
	height: 100%;
	width: 100%;
	background: #000000;
	position: absolute;
	top: -9999px;
	-moz-opacity:0.75;
	-khtml-opacity: 0.75;
	opacity: 0.75;
	filter:alpha(opacity=75);
}

#window_tem {
        width: 340px;
	height: 240px;
	margin: -120px 0 0 -170px;
	padding: 0;
	border: 8px solid #353230;
	position: absolute;
	top: 50%;
	left: 50%;
	background: white ;
}
?

Parce que si c'est ca ca affiche plus rien du tout! \o/
Modifié par apericube (07 Aug 2009 - 20:41)
Nan nan ce que je dis c'est qu'un élément n'a aucune dimension s'il n'est pas dans le flux du document HTML. Donc, un élément avec un style display: none; aura un width et un height à 0. Et il faut savoir que jQuery ajoute ce style par défaut lors des fonctions fadeOut (à la fin) et fadeIn (au début).

Pour faire en sorte de faire disparaitre un élément de la page sans pour autant lui coller un display: none; il faut l'envoyer dans l'espace, c'est à dire à l'extérieur de ce qu'on appelle le viewport (la partie visible de la page dans ton navigateur) grâce aux propriétés left et top. En faisant ça, ton élément garde ses dimensions.
Ok mais si j'utilise pas du tout le display: none alors j'utilise pas non plus les fonctions Fadein/out si ?

Desole je suis trop inexperimenté (ou teubé!) pour traduire ces explications en code fonctionnel, un coup de pouce supplementaire serait donc bienvenu.
Ça ne règlera pas forcément ton problème étant donné que je n'ai pas eu le courage de lire la fonction du Slider (bien pourrie car déclarer les defaults à chaque appel hum, optimisation minable et j'en passe), mais voici ce que tu peux tenter :

Déjà
<div id="popup"></div> 
<div id="window_tem">...
Ensuite
#popup { 
    height: 100%; 
    width: 100%; 
    background: #000000; 
    position: absolute; 
    top: 0px;
    left: 0px;
    -moz-opacity:0.75; 
    -khtml-opacity: 0.75; 
    opacity: 0.75; 
    filter:alpha(opacity=75);
    display: none;
} 
 
#window_tem { 
    width: 340px; 
    height: 240px; 
    margin: -124px 0 0 -174px; /* Tu oublies les borders (8px/2) */
    padding: 0; 
    border: 8px solid #353230; 
    position: absolute; 
    top: -1000px; 
    left: -1000px; 
    background: white ; 
}

#window_tem.onair {
    top: 50%; 
    left: 50%; 
}
Enfin
function Show_Popup_tem(action, userid) {
    $('#window_tem').hide().addClass('onair').add('#popup').fadeIn('fast');
} 
function Close_Popup_tem() {
    var window_tem = $('#window_tem');
    window_tem.add('#popup').fadeOut('fast', function() {
        window_tem.removeClass('onair').show();
    });
}


Bien sur je n'ai pas testé mais à priori le Slider a besoin d'un conteneur avec des dimensions (et là plus besoin de prouver qu'il est vraiment naze). Donc tu le mets offair (en dehors du viewport), là où il est préparé au document ready par le Slider. Au moment de le faire apparaitre, tu le fais disparaitre (oui je sais) pour le fadeIn en compagnie du popup. Petit rappel, le "10" que tu indiques sont des millisecondes. Préfère un "fast" (400ms).
Salut Ze Nenex, merci pour ton aide. En fait ca fait pareil qu'avant a peu pres. Je viens de me rendre compte aussi que, comme le CRETIN que je suis j'ai oublie d'uploader easyslider.js si bien que la version popup que tu as vu en demo etait incomplete et tres differente niveau resultat. Je sais pas si ca importe mais bon.

En tout cas mon probleme (combiner lightbox et slider) semble etre assez repandu, il y a par exemple cet autre post similaire et non resolu : http://forum.alsacreations.com/topic.php?fid=5&tid=41470&s=slider

Une fois encore je me trouve con car je suis incapable d'implementer exactement tes recommendations ("tu le mets offair (en dehors du viewport) . . . Au moment de le faire apparaitre, tu le fais disparaitre"), car je suis vraiment beginner en JS (je suis en train de lire JS : The Missing Manual donc je me soigne!)

Mais bon si t'en as marre je comprendrai !