11484 sujets

JavaScript, DOM et API Web HTML5

Pages :
bonjour à tous,

Je suis novice en js,
Lorsqu'on hover sur un li avec un attribut "projet 1" la div wrapper avec le meme attribut s'affiche. Je pense qu'en ciblant l'attribut du li avec onmouseover et en utilisant this y a moyen mais je n'arrive vraiment pas à le mettre en place ...

voici ce que j'essaye de faire:
( il reste plein truc pas utilisé c'est le foutoir dsl mais je m'en sort pas)
https://codepen.io/nwx/pen/PEbbMz

var work = work.getAttribute('alt');

work.mouseover = function() {
  (overflow_fullpage > this).classList.add('page_visible');               }
work.mouseout = function() {      
	 wrapper_page.classList.remove('page_visible');                     
}
work.mouseup = function() {      
	 wrapper_page.classList.add('page_visible');                         }


lorsque qu'on hover li, wrapper_page avec l'attribut du li s'affiche, ensuite lorsque l'on relâche le clique le wrapper_page dois s'afficher et rester. touche precedent sur la gauche.

je sais pas si j'ai été clair ...

Merci de votre aide
Modifié par dew (26 Dec 2017 - 22:34)
Modérateur
Bonjour,

Effectivement, ce n'était pas très clair ! Smiley cligne

Mais bon, je pense finalement avoir compris la question.

Tout d'abord, il y a des erreurs dans ton html. En particulier il y a un </div> en trop juste avant </main>. J'aurais par ailleurs mis la balise <script> avant le </body>.

Une fois ça fait, on peut s'attaquer à la question.

1) var work = work.getAttribute('alt'); ne veut rien dire

2) la fonction document.querySelector() récupère le premier élément dans le DOM correspondant au sélecteur que tu lui mets en paramètre. Or ici, tu as des listes d'éléments à récupérer. Il faut donc à certains endroits de ton code utiliser document.querySelectorAll() au lieu de document.querySelector(), et ensuite faire une boucle sur la liste d'éléments que cette fonction va renvoyer.

3) en ce qui concerne les "li", déjà, on constate que dans le code, l'attribut "alt" est sur les "a" contenus dans les "li" et non pas sur les "li" eux-mêmes.

4) je propose donc la solution suivante :
- on récupère la liste des éléments "a" contenus dans les "li" et qui ont la classe "work".
- on affecte à l'attribut "mouseover" de chacun de ces éléments une fonction qui, au moment où un hover se produit, va rechercher les autres éléments sur lesquels il faut faire une action en utilisant la valeur de l'attribut "alt" des "a". Un code possible est le suivant (note au passage l'emploi de addEventListener() dont je te conseille l'utilisation partout ailleurs dans ton code) :

EDIT: version simplifiée ci-dessous

/// HOVER PROJECT

var works = document.querySelectorAll('li a.work');
var k,km,s,f;
km = works.length;
for (k=0;k<km;k++)
{
	f = function() {
		var a, wrapper_work;
		a = this.getAttribute('alt');
		wrapper_work = document.querySelector('.wrapper_page.work[alt="'+a+'"]');		
		if (wrapper_work)
		{
			wrapper_work.classList.add('page_visible');
			overflow.classList.add('overflow_hidden_menu');
			click_previous.classList.add('previous_visible');
 	 		// etc...
 	 	}
	};
	works[k].addEventListener("mouseover", f, false);
}


Amicalement,
Modifié par parsimonhi (27 Dec 2017 - 12:11)
Modérateur
Bonjour,

Il me semble que faire disparaitre une liste lorsqu'on fait un hover sur l'un de ses éléments n'est pas très pratique pour l'utilisateur. Ça l'oblige à contourner les éléments qu'il ne veut pas sélectionner, sinon, la liste disparait au passage de la souris sur ces autres éléments.

Il vaut sans doute mieux laisser la liste visible là où elle est, pour pouvoir survoler tranquillement les différents éléments de la liste.

Amicalement,
bonjour,

déjà merci,

j'ai aussi poussé mes recherches un peu plus loin:

L'effet se rapprocherai de ce site:
http://www.controlfilms.tv/

j'imagine qu'il y a moyen d'appeler les pages html dans un div vide.

en jquery:
$( "#content" ).load( "ajax/test.html div#content" );

donc cibler les .work en hover avec une class ou un alt et ajouter à chaque fois
.load et charger la page html dans la div. mais j'aimerai bien automatiser le truc, pas envie de modifier ou rajouter des lien html dans le js par aprés.

Pas certain que ce soit la meilleur façon de faire?

J'ai vu qu'il y avait la même méthode avec $.get()?
Modifié par newger (27 Dec 2017 - 19:27)
Modérateur
Bonjour,

Si tu souhaites faire un chargement via ajax, le principe reste exactement le même que celui que j'ai proposé ci-dessus, sauf qu'on rajoute en plus un appel à AJAX.

Ci-dessous un exemple de code (à rajouter à la fin de ton code javascript dans l'exemple codepen que tu as donné), en supposant que tu as mis les sections concernant le projet1 dans un fichier appelé "projet1.html" et les sections concernant le projet2 dans un fichier appelé "projet2.html". Et évidemment il faut retirer ces sections du code html principal de ton exemple codepen en ne laissant que <div class="wrapper_page work" alt="projet1"></div> et <div class="wrapper_page work" alt="projet2"></div>, et ça devrait fonctionner :
// HOVER PROJECT

var works = document.querySelectorAll('li a.work');
var k,km,s,f;
km = works.length;
for (k=0;k<km;k++)
{
	f = function() {
		var a, wrapper_work;
		a = this.getAttribute('alt');
		wrapper_work = document.querySelector('.wrapper_page.work[alt="'+a+'"]');		
		if (wrapper_work)
		{
			var xhr = new XMLHttpRequest();
			xhr.onreadystatechange = function() {
				if (this.readyState == 4 && this.status == 200) {
					wrapper_work.innerHTML = this.responseText;
				}
			};
			xhr.open("GET",a+".html",true);
			xhr.send();
			wrapper_work.classList.add('page_visible');
			overflow.classList.add('overflow_hidden_menu');
			click_previous.classList.add('previous_visible');
 	 		// ajouter ici tout autre action
 	 	}
	};
	works[k].addEventListener("mouseover", f, false);
}


Amicalement,
super merci !! par contre j'avoue que je comprend pas encore tout dans ton code,

c'est quoi cette syntaxe +a+ ? [alt="'+a+'"]'

Et ceci j'imagine que c'est l'appel de la page dans wrapper_work mais c'est tellement différent de ce que j'avais vu, tu peux me commenter un peu plus pour que je comprenne mieux ?

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
wrapper_work.innerHTML = this.responseText;
}
};
xhr.open("GET",a+".html",true);

il n'y a pas un autre moyen de reprendre ça avec .hidde, .show ??

wrapper_work.classList.add('page_visible');
overflow.classList.add('overflow_hidden_menu');
click_previous.classList.add('previous_visible');
// ajouter ici tout autre action

ensuite le code prend en compte le hover mais que ce se passerai t'il lors du clique, la page dois rester active apres avoir cliqué, meme si on hover out le lien^^

dsl après je t'ennuie plus ^^
Modérateur
newger a écrit :
c'est quoi cette syntaxe +a+ ? [alt="'+a+'"]'

a est une variable. Un peu plus haut dans le code on a la ligne a = this.getAttribute('alt'); qui signifie qu'on met dans la variable a le contenu de l'attribut 'alt' de l'objet "this" ("this" étant ici l'élément sur lequel on fait le hover). a va donc valoir "projet1" ou "projet2" selon qu'on est en train de faire un hover sur le li du projet 1 ou le li du projet 2. Ensuite, '.wrapper_page.work[alt="'+a+'"]' est une bête concaténation de chaines de caractères. On réunit la chaine '.wrapper_page.work[alt="' avec le contenu de a et la chaine '"]'. Si a vaut "projet1", le résultat sera '.wrapper_page.work[alt="projet1"]' qui est le sélecteur css pour cibler un élément ayant pour classes "wrapper_page" et "work", et ayant un attribut "alt" avec la valeur "projet1". Et si a vaut "projet2", le résultat sera '.wrapper_page.work[alt="projet2"]', qui va cibler un élément ayant pour classes "wrapper_page" et "work", et ayant un attribut "alt" avec la valeur "projet2".

newger a écrit :
Et ceci j'imagine que c'est l'appel de la page dans wrapper_work mais c'est tellement différent de ce que j'avais vu, tu peux me commenter un peu plus pour que je comprenne mieux ?

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 &amp;&amp; this.status == 200) {
wrapper_work.innerHTML = this.responseText;
}
};
xhr.open("GET",a+".html",true);

Oui, il s'agit du code qui va mettre le contenu des fichiers "projet1.html" et "projet2.html" dans les éléments de classe "wrapper_work" correspondants. Soit tu mets dès le départ tous les contenus des sections des projets dans ton html (comme c'était le cas dans ton codepen initial) et alors tu n'as pas besoin de cette partie, soit tu mets ces sections dans des fichiers "projet1.html", "projet2.html", ... et alors il te faut bien un moyen pour inclure le contenu de ces fichiers dans ta page. Le code que j'ai mis ici est du javascript pur qui utilise la technique qu'on appelle AJAX. On peut faire plus court si on utilise jquery, mais il faut inclure jquery dans la page (ce qui rallonge pas mal le code de la page), et fondamentalement, ça revient au même car jquery fera lui aussi de l'AJAX, mais en te simplifiant (un tout petit peu) la vie.

newger a écrit :
il n'y a pas un autre moyen de reprendre ça avec .hidde, .show ??

Je ne vois pas trop ce que tu veux dire (.hide et non pas .hidde? .hide et .show de jquery?). Les .hide et .show de jquery vont montrer ou cacher des éléments qui sont déjà dans la page. AJAX, lui, va charger a posteriori dans la page des éléments qui n'y sont pas lors de l'affichage initial de la page (l'avantage étant que du coup, la page s'affichera initialement plus vite puisqu'elle ne contiendra pas encore le code correspondant aux projets et en particulier les super belles mais aussi super grosses images que tu ne vas pas manquer d'y mettre ! Smiley cligne ).

newger a écrit :
wrapper_work.classList.add('page_visible');
overflow.classList.add('overflow_hidden_menu');
click_previous.classList.add('previous_visible');
// ajouter ici tout autre action

ensuite le code prend en compte le hover mais que ce se passerai t'il lors du clique, la page dois rester active apres avoir cliqué, meme si on hover out le lien^^

La page reste active sauf qu'en l'état actuel du code, on cache la liste des li dès qu'on fait un hover sur l'un d'eux. Du coup, on ne peut plus cliquer dessus puisqu'on ne les voit plus, mais ils sont toujours là cachés quelque part. C'est pourquoi dans mon message précédent, j'indiquais que c'était une mauvaise idée de cacher cette liste de li lors d'un hover. Ce n'est pas un problème de javascript mais de design qui doit être corrigé dans le css. Lorsqu'un élément de classe "wrapper_work" devient visible (c'est à dire ici qu'on lui donne en plus la classe "page_visible") il faut faire en sorte que ça ne cache pas les li. Bref, il faut modifier selon moi ton css afin que cette liste de li reste visible après un hover. Et pour avoir un design cohérent, je pense qu'il faut aussi les garder visibles lors d'un click comme c'est d'ailleurs le cas dans le site http://www.controlfilms.tv/ dont tu veux t'inspirer.

Amicalement,
Merci beaucoup pour toutes ces explication et d'avoir pris le temps surtout ^^.

Le système d'hover ne cache pas le menu dans mon design, il affiche une partie de la page avec un overflow: hidden. C'est le click qui vient révéler la page, et remplacer le menu par la barre précédente. D'ailleurs le lien précédent peut être géré differement ?
Ceci dit t'a remarque de garder la visibilité du menu même si plus accessible est très juste car au final on revient plus souvent en arrière avec le navigateur, ou bien on click dans l'espace vide, du coup un bouton précédent est il vraiment crédible ...
Modifié par newger (27 Dec 2017 - 23:23)
Modérateur
newger a écrit :
Le système d'hover ne cache pas le menu dans mon design, il affiche une partie de la page avec un overflow: hidden.

C'est le click qui vient révéler la page, et remplacer le menu par la barre précédente.

Hum ? J'avais compris que le hover et le click devaient faire la même chose.

Note au passage que ta fonction dans ton codepen concernant le click ne marche pas comme elle le devrait. Elle affiche systématiquement le projet 1. Ceci est dû au fait que ton click_work.onclick = function() { ... } ne concerne que le premier li. Quand tu cliques sur un autre li, tu ne fais que ré-afficher la page sans passer par cette fonction (et donc sans rien faire).

Pour que cette fonction marche, il faudrait un code du même genre que celui que je t'ai proposé pour le hover. D'ailleurs, j'ai fait une maladresse dans ce code. La création de la fonction f devrait se faire en dehors de la boucle (initialement, j'utilisais la variable k dans cette fonction c'est pourquoi je l'avais mise dans la boucle, mais dans sa version actuelle, la définition de cette fonction n'a plus aucune raison d'être dans la boucle). Il y avais aussi un problème de wrapper_work précédent qui n'était pas caché correctement. Si tu veux tester dans ton codepen actuel (en oubliant pour l'instant l'action sur le hover, les actions concernant les filtres et les picture resizes qui ne sont pas au point), remplace click_work.onclick = function() { ... } (qui ne peut pas fonctionner correctement en l'état) par :
var works = document.querySelectorAll('li a.work');
var k,km,s,f;
km = works.length;
f = function() {
	var a, wrapper_work;
	a = this.getAttribute('alt');
	wrapper_work = document.querySelector('.wrapper_page.work[alt="'+a+'"]');		
	if (wrapper_work)
	{
		previous_wrapper_work = document.querySelector('.page_visible');
		if (previous_wrapper_work) previous_wrapper_work.classList.remove('page_visible');
		wrapper_work.classList.add('page_visible');
		overflow.classList.add('overflow_hidden_menu');
		// ajouter ici tout autre action
	}
};
for (k=0;k<km;k++)
{
	works[k].addEventListener("click", f, false);
}


newger a écrit :
D'ailleurs le lien précédent peut être géré differement ?

On peut toujours faire différemment quelque soit ce qu'on fait dans le web ! Smiley cligne

newger a écrit :
Ceci dit t'a remarque de garder la visibilité du menu même si plus accessible est très juste car au final on revient plus souvent en arrière avec le navigateur, ou bien on click dans l'espace vide, du coup un bouton précédent est il vraiment crédible ...

Il n'a en effet que peu d'intérêt si les li restent visibles.

Amicalement,
Modifié par parsimonhi (28 Dec 2017 - 08:24)
OK Donc je suis entrain de refaire un fichier propre avec système de filtre, chargement de page extérieur html ( votre code va bien m'aider je posterai le tout bientôt).
Je pense renommé ce topic "la mine du js"

EDIT:
Bon je suis repartit de zéro:
Ca ne fonctionne pas, j'ai merdé un truc, y aurai t'il moyen de me montrer avec un lien http:// plutôt que le (a+.html); ??
Et aussi il ne faut pas indiquer le chemin d'accès au fichier .html ? il va direct le chercher dans le même dossier que le fichier js ??

Mon nouvel exemple:
https://codepen.io/nwx/pen/dJNEdj?editors=1010

j'ai un problème de parenthèse en fin function ... y en a qu'une qui fonctionne
Modifié par newger (29 Dec 2017 - 12:13)
T'a fais bordel ici :

$(window).load(function(){
  $('.body_code').addClass('window_load');
}
  return;
)}; 


un return seul, ça n'existe pas, il faut faire un return "quelque chose".
un return dans un $(document).ready(function() ne sert strictement à rien. un return se voit généralement à la fin d'une fonction pour retourner un résultat, un état..
un $(window).load(function() dans $(document).ready(function() ne sert à rien
tu as oublier une parenthèse fermant après le )}; tel que )});

voila
Modifié par JENCAL (29 Dec 2017 - 14:20)
Modérateur
Bonjour,

JENCAL a écrit :
un return seul, ça n'existe pas, il faut faire un return "quelque chose".


Hum ! Smiley cligne Va falloir réviser tes cours ! Au milieu du code de la fonction, ça sert à terminer la fonction immédiatement. Par contre, c'est vrai qu'un "return;" en fin de fonction n'a pas d'utilité puisqu'on sort de la fonction juste après de toute façon.

Amicalement,
Modérateur
newger a écrit :
Bon je suis repartit de zéro:
Ca ne fonctionne pas, j'ai merdé un truc, y aurai t'il moyen de me montrer avec un lien http:// plutôt que le (a+.html); ??
Et aussi il ne faut pas indiquer le chemin d'accès au fichier .html ? il va direct le chercher dans le même dossier que le fichier js ??


Bon, on ne va jamais y arriver comme ça. Il va falloir que tu te fasses un tuto javascript parce que là, tu donnes l'impression de coder au hasard, et ça va prendre des années si on doit corriger chaque virgule de ton code. Smiley cligne

Concernant ton exemple codepen, tout d'un coup tu te mets à faire du jquery. Admettons, mais si tu débutes en javascript, il n'est pas clair que ça te rende les choses plus facile, parce que ça t'oblige à apprendre quand même un minimum de javascript plus apprendre jquery ! Ceci étant, essayer de comprendre comment utiliser jquery te servira tôt ou tard (mais faut faire les choses dans l'ordre : d'abord les bases en javascript et plus tard jquery).

Toujours concernant ton exemple codepen, si tu utilises du jquery, il faut charger jquery dans la page sinon, les fonctions de jquery ne marcheront pas. Et ce sera pareil sur ton site plus tard, il faudra quelque part une instruction qui chargera jquery dans la page. Parce que jquery est une extension de javascript (en gros, jquery, c'est un fichier js que tu inclus dans ta page). Dans codepen, cela se fait en cliquant sur le bouton "settings". Cherche des exemples avec jquery dans codepen faits par d'autres, regarde ce qu'ils mettent dans leur settings, et mets la même chose dans les settings de ton exemple codepen.

EDIT: je viens de voir que tu inclus jquery dans le code html. Donc, déjà, jquery, ça devrait le faire.

Concernant le chargement d'un fichier via ajax dans une page, commence par faire un exemple simple en javascript pur. Si tu ne veux pas te compliquer la vie avec des chemins devant les noms de fichiers, mets le code de ta page principale et le code du fichier html que tu veux insérer dans ta page dans le même dossier.

Une exemple simple complet récupérant un fichier en utilisant AJAX (essaie de tout comprendre, fais des modifications pour voir ce que ça donne, essaie de charger plusieurs fichiers dans ta page, .... et ensuite, on pourra avancer) :

<!DOCTYPE html>
<html>
<head>
	<title>Exemple en AJAX</title>
</head>
<body>
<h1>Mon bel exemple en AJAX</h1>
<p>
Cet exemple va charger le contenu du fichier "projet1.html" dans la div ayant pour id "toto".
</p>
<div id="toto"></div>
<script>
function myAjax(fileName,targetId)
{
	// cette fonction fait ce qu'on appelle de l'ajax
	// elle récupère le fichier html ayant pour nom fileName
	// et met le code html qu'il contient dans l'élément html ayant pour targetId pour id
	var xhr = new XMLHttpRequest();
	var e = document.getElementById(targetId);
	xhr.onreadystatechange = function() {
	if (this.readyState == 4 && this.status == 200) {
		e.innerHTML = this.responseText;
		}
	};
	xhr.open("GET",fileName,true);
	xhr.send();
}

// la ligne ci-dessous va exécuter la fonction ajax
// mais seulement une fois que la page sera complètement chargée
window.addEventListener("load", function(event) {
	// on appelle la fonction ajax
	// dans la fonction myAjax, fileName aura la valeur "projet1.html", et targetId aura la valeur "toto"
	myAjax("projet1.html","toto");
});
</script>
</body>
</html>

Amicalement,
Modifié par parsimonhi (29 Dec 2017 - 19:11)
Meilleure solution
upload/1514571204-69033-goodcaprture.jpg Je fais le test, donc ici mon infrastructure est bonne un dossier avec index.html et projet.html? et oui je vais bosser ça sérieusement.

ceci dit sur l'exemple d'hier, ici en local un alert sur le "a" récupère bien le Alt: "projet 1" donc il le voit, il ne trouve juste pas le fichier projet1.html qui est pourtant dans le même dossier.
Modifié par newger (29 Dec 2017 - 19:13)
Modérateur
newger a écrit :
upload/1514571204-69033-goodcaprture.jpg Je fais le test, donc ici mon infrastructure est bonne un dossier avec index.html et projet.html? et oui je vais bosser ça sérieusement.

ceci dit sur l'exemple d'hier, ici en local un alert sur le "a" récupère bien le Alt: "projet 1" donc il le voit, il ne trouve juste pas le fichier projet1.html qui est pourtant dans le même dossier.


"projet 1"avec un espace ou bien "projet1" sans espace ?

Amicalement,
projet1.html sans espace

tout est en local sur ma machine

EDIT: ok j'ai pigé ! il va chercher un http c'est pour ca qu'il trouve pas ... facon avec un lien ca marche pas non plus j avais testé ... aprés la syntaxe est surement differente.
Modifié par newger (29 Dec 2017 - 19:22)
Modérateur
newger a écrit :
projet1.html sans espace

tout est en local sur ma machine

EDIT: ok j'ai pigé ! il va chercher un http c'est pour ca qu'il trouve pas ... facon avec un lien ca marche pas non plus j avais testé ... aprés la syntaxe est surement differente.


Oui, mais dans le "alt", tu avais mis "projet 1" ou "projet1" ?

Amcialement,
Modifié par parsimonhi (29 Dec 2017 - 19:24)
Pages :