11497 sujets

JavaScript, DOM et API Web HTML5

Bonjour a tous,

Bon je ne suis pas très douée en javascript, mais j'ai essaye de me débrouiller seule. Mon code fonctionne, mais je me rends compte qu'avec toutes les données que j'ai je suis sur de pouvoir l'optimiser, mais je ne sais pas comment Smiley decu
Pas de version en ligne, qu'en local, donc voici un peu de code si ca peut vous éclaircir.

Niveau fonctionnalite, c'est une liste de titres (onglets) qui deroule horizontalement. Par defaut, la vue 1 est active pour qu'on voit directement le premier contenu. Et lorsqu'on clique sur la vue 2, cela affiche le contenu 2.

Mon code HTML ici

<div id="ca-container" class="ca-container">
  <div class="ca-wrapper">
    <div class="ca-item"><a href="#" id="view1" class="actif">Titre 1</a></div>
    <div class="ca-item"><a href="#" id="view2">Titre 2</a></div>
  </div>
</div>
<div class="tabcontents">
  <div id="view1" class="tabcontent actif">Contenu 1</div>
  <div id="view2" class="tabcontent">Contenu 2</div>
</div>


Mon code javascript (pas optimise)

$(".ca-item #view1").click(function() {
	$(this).addClass("actif");
	$('.ca-item #view2').removeClass("actif");
	$('.tabcontents #view1').addClass("actif");
	$('.tabcontents #view2').removeClass("actif");
});
$(".ca-item #view2").click(function() {
	$(this).addClass("actif");
	$('.ca-item #view1').removeClass("actif");
	$('.tabcontents #view2').addClass("actif");
	$('.tabcontents #view1').removeClass("actif");
});


Et mon code javascript optimise a ma facon, je reussis a afficher le bloc que je veux sauf que je si je clique sur le bloc 1 et ensuite le bloc 2 ils s'affichent l'un en dessous de l'autre. J'aimerais que le bloc 1 lui disparaisse si je clique sur le #2. Quelqu'un a une idee ?

$(".ca-item a").click( function affich_div()
{
	var id = $(this).prop('id');
	$('.tabcontents #' + id).css("display","block");
}
);

Modifié par fanny95 (13 Nov 2013 - 16:54)
salut,
déjà tu as des ID redondants, ce qui n'est pas faisable (view1 et 2) mais surtout la façon avec laquelle tu fais ça est plutôt moyenne. Si tu laissais tes liens pointer vers leurs contenus respectifs contenu (i.e <a href="#contenu1" /> ...) tu pourrais les récupérer par la suite et afficher directement l'élément avec l'ID vers lequel pointe ton lien mais tu gagneras surtout en accessibilité et en "bonne pratique" vu que si tu désactives JS, ta navigation serait impossible.


<div id="ca-container" class="ca-container">
  <div class="ca-wrapper">
    <div class="ca-item"><a href="#view1">Titre 1</a></div>
    <div class="ca-item"><a href="#view2">Titre 2</a></div>
  </div>
</div>
<div class="tabcontents">
  <div id="view1" class="tabcontent actif">Contenu 1</div>
  <div id="view2" class="tabcontent">Contenu 2</div>
</div>



var contents = document.querySelectorAll(".tabcontent");

$("#ca-container a").click(function(e) {
	(e.preventDefault) ? e.preventDefault() : (e.returnValue = false);
	
	var targetID = $(this).hash.substring($(this).hash.indexOf("#")+1),
		targetContent = document.getElementById(targetID);
	
	for(var x=0, l=contents.length; x<l; x++){
		$(contents[x]).removeClass("actif");
	}
	
	$(targetContent).addClass("actif");
}


Je n'ai pas testé donc je ne sais pas si c'est nickel.
Merci de ton aide Zelalsan
J'ai change mon code et ajoute tes modifications mais ca ne marche pas. L'url ne change pas et le contenu du bloc 2 ne s'affiche pas quand je clique Smiley decu
En fait, mon editeur de texte me dit qu'il y a un soucis a la ligne de fin. J'ai donc rajoute un ); apres la derniere }
Mais si je laisse ton code tel quel, cela change l'url mais pas le bloc de contenu.

Dans mon exemple, cela fonctionne, le seul probleme c'est qu'il affiche le bloc 1 et le bloc 2 en dessous. Il me faudrait une ligne javascript qui me permette de cacher l'autre bloc si je clique sur un autre.
Enfin vous comprenez ou je suis pas clair peut etre lol Smiley smile
Modifié par fanny95 (13 Nov 2013 - 16:59)
Bon c'est parce que je n'utilise pas JQuery et j'ai essayé de te le donner avec.
Avec un code en JS brut (que j'ai testé) ça devrait le faire

function addEvent(a,b,c,d){d = !d && false;(a.addEventListener)?a.addEventListener(b,c,d):a.attachEvent('on'+b,c);}

var contents = document.querySelectorAll(".tabcontent"),
	liens = document.querySelectorAll("#ca-container a");

function clicked(e){
	(e.preventDefault) ? e.preventDefault() : (e.returnValue = false);
	
	var currentLink = e.target || e.srcElement,
		currentHash = currentLink.hash,
		targetID = currentHash.substring(currentHash.indexOf("#")+1),
		targetContent = document.getElementById(targetID);
	
	for(var x=0, l=contents.length; x<l; x++){
		contents[x].className = contents[x].className.replace(" actif", "");
	}
	
	targetContent.className += " actif";
}

for(var x=0, l=liens.length; x<l; x++){
	addEvent(liens[x], "click", clicked, false);
}


Avec la même structure HTML que la précédente
Euuuh... Je suis sensé voir quoi Smiley biggrin ? Perso j'ai testé et ça marche et quand je clique sur les liens de ton menu, ça change bien les contenus.
Pour l'adresse du lien c'est fait exprès mais on peut faire en sorte que ça change.
Exacte autant pour moi, je cliquais sur l'image et non sur le texte. Je vais modifier ca en CSS de ce pas.
Merci pour ton aide ! Meme si je viens de reussir a moitie que mon code fonctionne. Mais je vais garder le tient.
Bon je comprends rien a ton code javascript mais pas grave Smiley cligne J'essayerais demain.
Juste peux tu me dire quelle ligne rajouter pour que cela change l'url ? Merciiiii
Modifié par fanny95 (13 Nov 2013 - 17:42)
Je t'en prie. Pour l'adresse tu rajoutes juste

location.href = currentHash;


après la déclaration des variables dans la fonction "clicked"
Merci beaucoup Zelalsan!
Et desolee de te deranger encore une fois, mais une autre question:
- Comment avoir ma class .actif dans la navigation afin que mon fond bleu change quand je clique sur une vignette ?
- En CSS, j'ai rajoute un display block et une hauteur a mes liens mais rien n'y fait, quand je clique au niveau de l'image (alors que le lien est bien la), ca ne change pas mon contenu Smiley decu
Modifié par fanny95 (13 Nov 2013 - 17:54)
Pas de problèmes, voici le code complet

function addEvent(a,b,c,d){d = !d && false;(a.addEventListener)?a.addEventListener(b,c,d):a.attachEvent('on'+b,c);}

var contents = document.querySelectorAll(".tabcontent"),
	liens = document.querySelectorAll("#ca-container a");

function clicked(e){
	(e.preventDefault) ? e.preventDefault() : (e.returnValue = false);
	
	var currentLink = e.target || e.srcElement,
		currentHash = currentLink.hash,
		targetID = currentHash.substring(currentHash.indexOf("#")+1),
		targetContent = document.getElementById(targetID);
	
	location.href = currentHash;
	
	for(var x=0, l=contents.length; x<l; x++){
		liens[x].className = liens[x].className.replace(" actif", "");
		contents[x].className = contents[x].className.replace(" actif", "");
	}
	
	currentLink.className += " actif";
	targetContent.className += " actif";
}

for(var x=0, l=liens.length; x<l; x++){
	addEvent(liens[x], "click", clicked, false);
}


ça supposera qu'il y ait autant de liens que de contenu si non il faudrait faire une boucle à part pour enlever la classe "actif" à tes liens.
Merci encore une fois ! Je vais vraiment me pencher sur ces codes javascript que tu m'as donne et décortiquer tout ça.

Le probleme que j'ai maintenant (eh oui toujours un) c'est que ma class .actif dans ma navigation que j'avais mis par defaut dans mon HTML reste en .actif et ne s'efface pas lors du clique sur un autre avion.

Du coup deux solutions :
01- j'enlève mes .actif dans mon HTML et je vais essayer l'affichage par defaut du premier avion en javascript
02-Je garde mes .actif de mon premier avion dans mon HTML et en javascript il faut que j'enleve cette class aux autres avions des lors du clique

Quelle solution est la mieux selon toi ?
Modifié par fanny95 (13 Nov 2013 - 18:04)
Non c'est moi qui ai fait un code qui n'efface qu'une classe ajoutée. Il faut la laisser par défaut dans l'HTML, tu dois juste ajouter un espace avant " actif" au lieu de "actif". C'est possible de corriger ça avec une expression régulière mais un peu la flemme ^^.
C'est fou comment un espace peut changer une vie Smiley smile ) Merci encore pour tout =D
Moi je vais dodo il est quand meme 1h30. Bonne nuuiiiit
Bonjour, j'arrive après la bataille mais je veux juste donner une version Jquery pour ceux qui aiment :


.ca-container .tabcontents > .tabcontent{
    display : none;
}
.ca-container .tabcontents > .tabcontent.actif{
    display : block;
}

ul.ca-wrapper li.ca-item{
    display: inline;  
}
div.ca-wrapper div.ca-item{
    float: left;
    margin-right: 5px;
}
div.tabcontents{
    clear: both;
}


<h3>Tab 1</h3>
<div id="ca-container" class="ca-container">
    <div class="ca-wrapper">
        <div class="ca-item"><a href="#view1">Titre 1</a></div>
        <div class="ca-item"><a href="#view2">Titre 2</a></div>
    </div>
    <div class="tabcontents">
      <div id="view1" class="tabcontent">Contenu 1</div>
      <div id="view2" class="tabcontent actif">Contenu 2</div>
    </div>
</div>

<h3>Tab 2</h3>

<div id="ca-container-2" class="ca-container">
    <ul class="ca-wrapper">
        <li class="ca-item"><a href="#view11">Titre 1</a></li>
        <li class="ca-item"><a href="#view22">Titre 2</a></li>
    </ul>
    <div class="tabcontents">
      <div id="view11" class="tabcontent">Contenu 1</div>
      <div id="view22" class="tabcontent">Contenu 2</div>
    </div>
</div>



$("div.ca-container").each(function(){

    var _this = $(this),
        _tabMenu = _this.find(".ca-wrapper:first"),
        _tabContainer = _this.find(".tabcontents:first"),
        _links = _tabMenu.find(".ca-item a"),
        _originalActifLink = _links.filter("[href=#" + _tabContainer.find(".actif:first").prop("id") +"]"),
        _actifLink = _originalActifLink.size() > 0 ? _originalActifLink : _links.first();
    
    
    _links.click(function(evt){
        
        evt.preventDefault();
        _tabContainer
        .find(".tabcontent")
        .removeClass("actif")
        .filter(this.hash)
        .addClass("actif");
        
    });
    _actifLink.trigger("click");        

});




Bon dans mon example le script js marche pour toutes les ossatures qui respectent l'ordre des classes, et permet en un seul script de gérer plusieurs tabs.

Il initialise le premier menu par défaut, si et seulement si il ne trouve pas un menu avec la classe actif par défaut

Voici un lien fiddle pour le voir en action


Attention à la partie css, car c'est en CSS que le show/hide se fait, c'est plus performant qu'un hide javascript pure
Modifié par qualithras (14 Nov 2013 - 01:27)