11540 sujets

JavaScript, DOM et API Web HTML5

Bonjour,
Je suis débutante en js, mais j'essaie tant bien que mal d'apprendre.

Donc voilà, j'essaie de créer un système d'onglet avec jquery. Je me suis basé sur ce tutoriel : -http://www.grafikart.fr/tutoriels/jquery/onglets-175

Mais comme je n'aimais pas le système d'ancre j'ai essayé de faire autrement en m'inspirant de "isotope" que j'utilise dans l'un des contenus des onglets.

Présentement, quand je load la page, tous les onglets sont en active et tout les contenu s'affichent l'un en dessous de l'autre...
Dès je clique sur un onglet, tout devient comme ça devrait être au départ, c'est à dire qu'un seul contenu s'affiche, là c'est bon...

Bref, je n'arrive pas à déterminer ma position de départ qui devrait en fait afficher uniquement le contenu du premier onglet et c'est ce premier onglet qui devrait être en "active"

Mon code html simplifié:
<section class="main-features">
    <ul id="tabs" class="tabs menu">
	<li><a data-toggle=".features" href="javascript:;">Caractéristiques</a></li>
        <li><a data-toggle=".mdl-accessoires" href="javascript:;">Accessoires disponibles</a></li>
        <li><a data-toggle=".files" href="javascript:;">Fichiers Téléchargeables</a></li>
    </ul>
    
    <div class="contenu">
        <article id="features" class="features">
            <h1>Caractéristiques</h1> 
        </article>
        
        <article class="mdl-accessoires" id="mdl-accessoires">
            <h1>Accessoires disponibles</h1>
        </article>
        
        <article id="files" class="files">
            <h1>Fichiers Téléchargeable</h1>
        </article>
    </div>
</section>


Voici où j'en suis au niveau du js, j'ai laissé certain bout de code en commentaire pour que ça vous donne une idée des différentes voie exploré.
jQuery(function($){
	
	$("#cameras section.main-features > div.contenu > article").css({
		background: "rgb(219, 219, 219)",
	});
	
	$('#tabs li').each(function() {
		
		//var selected = $(this).attr('data-toggle');
		var current = null;
		
		/*if(selected != ''){
			current = selected;
		}else{
			current = $(this).find('a:first').attr('data-toggle');
		}*/
		//alert (find('a:first'));
		
		//$(this).find('a[data-toggle=".'+current+'"]').addClass('active');
		$(this).find('a:first').addClass('active');
		$(current).siblings().hide();
		
		$(this).find('a').click(function(){
			var selected = $(this).attr('data-toggle');
			
			/*if(selected == current){
				return false;
			}else{*/
				$(this).parent().siblings().find('a.active').removeClass('active');
				$(this).addClass('active');
				$(selected).show().siblings().hide();
				current = selected;
			//}
		})
    });
});


D'avance, merci!
Modifié par juliesunset (10 Sep 2014 - 22:20)
Bonjour.

juliesunset a écrit :
Mais comme je n'aimais pas le système d'ancre j'ai essayé de faire autrement

Tout d'abord, je pense qu'au niveau de l'ergonomie et de l'accessibilité, c'est pourtant ce qu'il y a de mieux.

Ensuite, je pense déjà que tu te perds sur certaines portions de code, exemple :
$('#tabs li').each(function() {
	$(this).find('a:first').addClass('active');
})

Tu vas parcourir tous les li, puis tu ajoutes la classe active sur les a:first (mais de tous les li), je ne pense pas que c'est que tu veux.

Ensuite si tu ajoutes une classe sur ton contenu actif, tu peux gérer plus facilement en CSS le fait que certain soit caché au départ (et pas d'autres), je pense à un truc du genre :
http://jsfiddle.net/m85xka3j/1/

Et ça (ci-dessous), sauf si tu ne peux faire autrement, je te conseillerais de le faire en CSS, c'est fait pour :
$("section.main-features > div.contenu > article").css({
	background: "rgb(219, 219, 219)", // <- la virgule aurait été à supprimer en plus
})


Et puis si tu veux simplifier totalement, autant ne pas utiliser les data, et pas besoin de <a> non plus Smiley cligne :
http://jsfiddle.net/m85xka3j/2/
Modifié par SolidSnake (11 Sep 2014 - 10:11)
SolidSnake a écrit :
je pense qu'au niveau de l'ergonomie et de l'accessibilité, c'est pourtant ce qu'il y a de mieux.
En temps normal je n'aurait eu aucun problème avec les ancres, mais dans ce cas précis ça perturbe la navigation du site. Je préfère donc un système sans ancre.

SolidSnake a écrit :
Et ça (ci-dessous), sauf si tu ne peux faire autrement, je te conseillerais de le faire en CSS, c'est fait pour :
$(&quot;section.main-features &gt; div.contenu &gt; article&quot;).css({
	background: &quot;rgb(219, 219, 219)&quot;, // &lt;- la virgule aurait été à supprimer en plus
})

Cette couleur doit être appliqué uniquement si js est activé... donc je laisse.
D'ailleurs, j'aimerais aussi faire en sorte que le menu d'onglets n'apparaisse que si js est activé...

SolidSnake a écrit :
Ensuite, je pense déjà que tu te perds sur certaines portions de code, exemple :
$('#tabs li').each(function() {
	$(this).find('a:first').addClass('active');
})

Tu vas parcourir tous les li, puis tu ajoutes la classe active sur les a:first (mais de tous les li), je ne pense pas que c'est que tu veux.
Ben en fait, j'essaie de sélectionné le premier li d'une série de li dont le nombre n'est pas toujours le même d'une page à l'autre...

SolidSnake a écrit :
Ensuite si tu ajoutes une classe sur ton contenu actif, tu peux gérer plus facilement en CSS le fait que certain soit caché au départ (et pas d'autres), je pense à un truc du genre :
http://jsfiddle.net/m85xka3j/1/
Nope, j'ai déjà un rendu CSS si js n'est pas activé. Aucun contenu ne doit être caché dans ce cas précis.

SolidSnake a écrit :

Et puis si tu veux simplifier totalement, autant ne pas utiliser les data, et pas besoin de &lt;a&gt; non plus Smiley cligne :
http://jsfiddle.net/m85xka3j/2/


Merci pour ton commentaire, je regard ton code.


Pour donné une meilleur idée voici le rendu actuel d'une page type sans le système d'onglet -http://www.spypoint.com/FR/produits/camera-chasse-del-invisibles/produit-BF-10HD.html
Donc ceci, correspond au rendu qu'il doit y avoir sans js. J'essaie simplement d'ajouter une couche en js.
juliesunset a écrit :
Cette couleur doit être appliqué uniquement si js est activé... donc je laisse.
D'ailleurs, j'aimerais aussi faire en sorte que le menu d'onglets n'apparaisse que si js est activé...

A la rigueur au début de ton JS, tu colles un truc du genre :
$('html').addClass('js') // ou alors suppression d'une classe no-js qui serait par défaut sur ta page

Et comme ça tu gères ta couleur de bg en CSS, histoire de bien différencier les scripts et la mise en forme.

juliesunset a écrit :
Ben en fait, j'essaie de sélectionné le premier li d'une série de li dont le nombre n'est pas toujours le même d'une page à l'autre...

Ici le code sera plutôt :
$('#tabs li:first a') // avec le first sur le li et pas sur le a



juliesunset a écrit :
Nope, j'ai déjà un rendu CSS si js n'est pas activé. Aucun contenu ne doit être caché dans ce cas précis.

En utilisant la technique de mon premier point (ajout d'une classe sur la balise html ou body), tu peux cacher ton contenu quand tu as le JS.
Ah ouais! ça commence à être un peu plus claire...

Maintenant les onglets fonctionnent, mais j'ai un conflit avec le script isotope que j'utilise dans l'un des onglets, quand j'ouvre l'onglet en question, tous les éléments s'affichent les uns en dessous des autres au premier chargement....


jQuery(function($){
	
	$('html').addClass('js');
   
	$('#tabs li:first a, .contenu article:first').addClass('active');
		
	var $tabs = $('#tabs a');
    
	$tabs.click(function(e){
        	e.preventDefault();
        
        	var selected = $(this).attr('data-toggle');
        
        	$tabs.removeClass('active');
        	$(this).addClass('active');
        	$(selected).addClass('active').siblings().removeClass('active');
	})
});


<section class="main-features">

	<ul id="tabs" class="tabs bdr-orange-bottom">
		<li><a data-toggle=".features" href="javascript:;" class="active">Caractéristiques</a></li>
		<li><a data-toggle=".mdl-accessoires" href="javascript:;" class="">Accessoires disponibles</a></li>
		<li><a data-toggle=".files" href="javascript:;" class="">Fichiers Téléchargeables</a></li>
	</ul>
    
	<div class="contenu">
	<article id="features" class="features bdr-orange-top active">
		<h1 class="is-left bdr-orange-bottom">Caractéristiques</h1> 
		<div class="container">
			<div class="l-inline-block"> 
				<table class="caracteristiques">
					<tbody>
						<tr>
							<th align="left" class="is-left">Photo</th>
							<td align="right" class="is-right">Full&nbsp;HD</td>
						</tr>
						...
					</tbody>
				</table>
			</div>
			....
		</div>
	</article>
    
	<article id="mdl-accessoires" class="bdr-orange-top mdl-accessoires">
        	<h1 class="is-left bdr-orange-bottom">Accessoires disponibles</h1>
        	<div class="menu l-table-cell">
			<ul class="filtre" id="products-filter">
				<li><a href="javascript:;" data-filter=".alimentation">Alimentation</a></li>
                		<li><a href="javascript:;" data-filter=".autres">Autres</a></li>
                		<li><a href="javascript:;" data-filter=".eclairage-infrarouge">Éclairage infrarouge</a> </li>
                		<li><a href="javascript:;" data-filter=".installation-securite">Installation et sécurité</a></li>
                		<li><a href="javascript:;" data-filter=".memoires">Mémoires</a></li>
                		<li><a href="javascript:;" data-filter="*">Tout afficher</a></li>
			</ul>
		</div>
		<div id="produits" class="l-table-cell l-grid isotope">
			<div id="ad-12v" class="listing l-inline-block bdr-gray alimentation">
        			<a href="http://www.spypoint.com/FR/produits/adaptateur-ac-6-12-volts/produit-ad-12v.html" title="Adaptateur AC 6 à 12 volts">
                    			<h2 class="l-grid">Adaptateur AC 6 à 12 volts</h2>
                    			<img src="/images/products/power/AD-12V.png" alt="AD-12V" width="150" class="l-block" />
               			 </a>
				<!-- Btn add to cart -->
				<article id="price" class="mid">
					<p class="no"># AD-12V</p>
					<p class="online">Prix en ligne : <span>34,99 $ CA</span></p>
					<input type="button" class="cart_btn_add_item gradient-orange" itemid="AD-12V" data-str1="Ajouter au panier" data-str2="L'item a été ajouté!" value="Ajouter au panier">
				</article>
			</div>
		</div>
		...
	</article>
	<article class="files bdr-orange-top" id="files">
    		<h1 class="is-left bdr-orange-bottom">Fichiers Téléchargeable</h1>
		<div class="logiciel l-inline-block bdr-orange-left">
			<h2 class="is-left">Outils</h2>
			<div class="logiciel l-inline-block bdr-gray">
				<p>Logiciel qui permet d'assembler une série d'images prises en mode "time lapse" pour en faire une vidéo</p>
				<a href="/download/freeware/ImagesToVideo.zip" class="bouton"><span class="ico_file-download" aria-hidden="true"></span>Télécharger le fichier</a>
			</div>
		</div>
	</article>
	</div>
</section>


Entouka merci pour tes réponses!
Bonjour.

De quel JS isotope tu parles, celui-là je suppose ?

Si c'est le cas essaie de faire un reloadItems() dans ta boucle après l'affichage de ton onglet :
$('#tonContainer').isotope('reloadItems')
oui c'est bien ce isotope là dont je parle.

J'ai essayé le reloadItems comme tu suggère, mais ça ne change rien... Je ne le met peut-être pas à la bonne place? Je l'ais mis à la fin dans le " $tabs.click(function(e){ }) "
Ah je l'ai!

J'ai ajouté ceci dans la boucle:
$('.isotope').isotope({
	layoutMode: 'fitRows'
});



LE code final:
jQuery(function($){
	
	$('html').addClass('js');
   
	$('#tabs li:first a, .contenu article:first').addClass('active');
		
	var $tabs = $('#tabs a');
    
	$tabs.click(function(e){
        	e.preventDefault();
        
        	var selected = $(this).attr('data-toggle');
        
        	$tabs.removeClass('active');
        	$(this).addClass('active');
        	$(selected).addClass('active').siblings().removeClass('active');

        	$('.isotope').isotope({
			layoutMode: 'fitRows'
		});
	})
});



Merci pour ton aide!