Pages :
Bonjour,

Ma question se trouve grosso-modo dans le titre... J'ai 5-6 div déclarés dans le HTML, donc l'utilisateur télécharge le site complet dès sa première connexion (le site n'est pas très gros).

Toutes les div sont masqués, sauf la première et le JS s'occupe de masquer/afficher en fonction des actions pratiqués sur le menu.

Mon problème est que la barre d'adresse reste à : www.monsite.com/index.html

J'aimerais changer le index avec le nom des pages concerner. J'étais parti sur la voix du AJAX, mais il s'avère que c'est pas bon. On m'a parlé de la navigation avec des ancres mais je n'arrive à rien.

Je sollicite donc votre aide... Merci bien.
Hello,

Dans ton cas la navigation avec les ancres devrait s'implémenter en trois parties je pense :

1 - Dans ton menu, avoir des liens du type
<a href="#ancre">...</a>
+ le code javascript nécessaire pour afficher la partie correspondante. Ne pas utiliser de return false dans le onclick de sorte à ce que les lecteurs d'écran et les navigateurs clavier sautent au bon endroit sans que tu aies à t'en préoccuper. Normalement ça ne recharge pas la page.

2 - Dans la partie correspondante, ne pas oublier l'ancre
<div id="ancre">

3 - Et en javascript, faire en sorte que si #ancre est présent dans l'URL, ne pas masquer la partie qui y correspond.
Attention: faire en sorte que le javascript masque toutes les parties sauf celle visée et que par défaut tout soit affiché initialement, et non pas tout masquer par défaut et afficher seulement la bonne partie en javascript. La deuxième est mauvaise dans la mesure où le navigateur est incapable de sauter à la bonne partie dès le chargement de la page, puisqu'elle est masquée !
Tu peux chercher la présence de #ancre dans window.location ou document.location.
Ok, merci pour ta réponse.

Bon, je réponds un peu tard (vacances) mais j'ai pu avancer. Cependant, il reste toujours quelques problèmes. Alors globalement, le point 1 (href avec une ancre), ok. Le point 2, c'est bon aussi.

Donc quand je clique j'ai bien mes div qui se masquent et celle que l'on veut "voir" s'affiche correctement. Contrairement à se que tu expliques toutes mes div sont masqués sauf la première qui correspond a la page "Home". Sur les premières versions du site, toutes les div étaient affichés et on pouvait voir les div succédant à la première se masquer. Mais d'un point de vue de "l'oeil", l'effet n'était pas terrible.

Plusieurs choses me dérangent, la première je pense que je pourrais pas faire autrement (j'ai essayé plusieurs combines), c'est l'adresse qui se termine par #monAncre. Je trouve pas ça terrible mais bon, si on peut faire autrement, je reste à l'écoute. (j'ai essayé avec des regex de localiser l'ancre et de la modifier mais du coup le navigateur essaye d'ouvrir une page qui n'existe pas).

Autre point, si le contenu dépasse de la page, alors il se cale en haut. Du coup le menu (qui es une barre en haut mais pas fixe) remonte et se retrouve caché. D'un point de vue ergonomie je trouve pas ça terrible. Y'aurait il un moyen ?

Dernier point et c'est le plus important : si on entre dans le navigateur l'adresse du site avec une ancre, rien ne se passe. On arrive sur la page "Home" et non sur la page "contact" (par exemple). Que dois-je faire ? Un petit JS ?

Merci pour ces précisions...
Modifié par MagicCarpet (16 Aug 2013 - 22:33)
1 - Si tu veux faire les choses correctement et sans bidouille, oui, c'est la seule solution.

2 - Demande aux experts de CSS. JE pense que ça pourrait passer par position: fixed, ne je vois pas trop d'autre solution.

3 - Oui il te faut un script qui regarde l'URL dès le chargement pour ne pas masquer la div désirée.
Si tu veux...
Le script suivant devrait masquer toutes les div que tu veux sauf celle référencée dans l'URL, s'il y en a une. S'il n'y en a pas, elles sont toutes masquées.

Exemple écrit directement dans la zone de réponse en 5 minutes, donc pas testé.

window.onload = function(){
var divs = ['one', 'two', 'three', 'four', 'five'];
for (var i=0; i<divs.length; i++) {
var name = divs[ i ];
if (document.location.indexOf('#'+name)<0) document.getElementById(name).style.display = 'none';
}
};


Ca pourra te donner une vague idée de ce à quoi je pense depuis le début de ce topic. A toi d'adapter à tes besoins.

EDIT: Arf, il y a toujours ce bug à la con avec le i entre crochets dans les zones de code
Modifié par QuentinC (18 Aug 2013 - 17:03)
Merci pour ta réponse.

Bon, j'ai fais un peu ma "feignasse" car je me douté qu'avec document.location il y'avait moyen... Mais (comme je le craignais)... Ca coince !

Alors voici mon bout de code (première partie) :


var location = new String(document.location);
console.log('mon log : ' + location);
var position = location.indexOf('#');
console.log('ma loc : ' + position);
// On incrémente pour ne pas prendre en compte le # de l'ancre.
var callDiv = location.slice(++position);
console.log('ma div : ' + callDiv);


(j'ai une erreur si je fais ceci : document.location.indexOf()).
Ceci fonctionne. Au premier appel de la page, il initialise les variables mais la position est bien inférieure à 0. Normal, car si on entre l'adresse "de base", aucune ancre n'est présente.

Si par contre, on ajoute une ancre, après l'appuis de la touche entrée ce code est à nouveau exécuté et les console.log me renvois les bonnes valeurs (en tout cas, celles que j'attends).

Mais la div que j'attends à l'affichage ne s'affiche pas. En fait il y'a un temps assez long de chargement (trop long même, se qui n'est pas normal). Voici mon code :


if(location.indexOf('#')) {
	$('#menu-contact').click();
});


Ayant des id dans les <a> de mon menu, l'idée est de simuler un click. Mais ceci ne fonctionne pas du tout.
Modifié par MagicCarpet (18 Aug 2013 - 21:07)
a écrit :
(j'ai une erreur si je fais ceci : document.location.indexOf()).

Dans la précipitation, j'ai effectivement oublié que document.location n'était pas une string; donc pas de méthode indexOf. Bien vu pour la parade.

a écrit :
Ayant des id dans les <a> de mon menu, l'idée est de simuler un click. Mais ceci ne fonctionne pas du tout.

Ben non. En cliquant sur le lien, tu recharges la page, et ça provoque une boucle sans fin !

Il faut t'inspirer de mon exemple et masquer toutes les div sauf celle qui est demandée dans l'URL.

Fais bien attention à tout afficher par défaut et masquer ensuite tout ce qui n'est pas demandé, plutôt que tout masquer par défaut et afficher ensuite seulement ce qui est demandé. C'est une question d'accessibilité, et c'est primordial parce que sinon, un lecteur d'écran ne pourra pas sauter à la bonne ancre si elle est initialement masquée.
QuentinC a écrit :
Bien vu pour la parade.


Merci Smiley confused

QuentinC a écrit :
Ben non. En cliquant sur le lien, tu recharges la page, et ça provoque une boucle sans fin !


Eu, oui, effectivement...

QuentinC a écrit :
Fais bien attention à tout afficher par défaut et masquer ensuite tout ce qui n'est pas demandé, plutôt que tout masquer par défaut et afficher ensuite seulement ce qui est demandé. C'est une question d'accessibilité, et c'est primordial parce que sinon, un lecteur d'écran ne pourra pas sauter à la bonne ancre si elle est initialement masquée.


Bon alors je n'ai pas changé ma première approche que j'ai expliqué plus haut, c'est à dire que je masque toutes mes div sauf la première, au premier chargement de la page. Est-ce que j'ai bon ou pas ? Ton texte me laisse un léger doute. Par contre, merci pour cette info, je ne savais pas et du coup j'ai adapté mon JS (inverse de se que je faisais auparavant) : actuellement, j'affiche tout (une fois que tu cliques sur un menu) et je ne masque à nouveau tout sauf la div concerné.

Pour en revenir à mon problème initial, maintenant ça fonctionne. En fait, j'ai fais ceci :
(je remet tout avec les log, le code n'est pas définitif)

console.log('mon log : ' + document.location);
var location = new String(document.location);
var position = location.indexOf('#');
console.log('ma loc : ' + position);
// On incrémente pour ne pas prendre en compte le # de l'ancre.
var callDiv = location.slice(++position);
console.log('ma div : ' + callDiv);

if(position) {
	$hideMyDivs.removeClass('hide');
	$('#' + callDiv).siblings('article').addClass('hide');
}


Donc, si tu ouvres un navigateur et que tu entres l'adresse avec une ancre, on affiche la page demandé (on voit d'abord la page home qui est affiché par défaut, mais bon, c'est mieux que tout affiché je pense. Faudrait peut être faire une barre de progression ?)

Bon, le dernier problème de cette méthode (la prochaine fois je ferais avec du PHP/AJAX je pense) c'est que si tu es déjà sur le site et que tu entre à la main une ancre, il se passe ça :
- Firefox : rien ne se passe, on dirait que la touche entrée est désactivé
- Safari, ça tourne dans le vide.

Es-tu au courant de ça ? Existe t'il des solutions ?
Dans tous les cas, merci pour ton aide.
Modifié par MagicCarpet (19 Aug 2013 - 20:41)
a écrit :

Bon alors je n'ai pas changé ma première approche que j'ai expliqué plus haut, c'est à dire que je masque toutes mes div sauf la première, au premier chargement de la page. Est-ce que j'ai bon ou pas ? Ton texte me laisse un léger doute. Par contre, merci pour cette info, je ne savais pas et du coup j'ai adapté mon JS (inverse de se que je faisais auparavant) : actuellement, j'affiche tout (une fois que tu cliques sur un menu) et je ne masque à nouveau tout sauf la div concerné.

Je réessaye une fois pour être sûr d'être bien clair, ce n'est pas toujours facile de bien expliquer du premier coup. L'idée est la suivante :
1. Au cas où js est désactivé ou indisponible, toutes les div doivent être visibles par défaut. Donc pas de display:none en dur en CSS
2. Si le js est activé, le script se lance au chargement de la page
2.1. S'il y a une ancre, masquer toutes les div sauf celle qui est visée
2.2. S'il n'y a pas d'ancre, masquer toutes les div sauf celle qui représente la page d'accueil
3. Au clic sur un lien d'une ancre
3.1. Dans certains navigateurs, la page se recharge; qu'il y ait script ou pas, la div visée n'a jamais été masquée donc le navigateur et les lecteurs d'écran vont sauter au bon endroit
3.2. Dans certains autres navigateurs, la page ne se recharge pas. Dans ce cas, il faut masquer la div précédemment affichée et montrer la nouvelle à la place. Ne pas return false dans le onclick pour permettre aux lecteurs d'écran de sauter au bon endroit quand même

Je prévois deux cas 3.1 et 3.2 parce qu'en fait, j'ai l'impression que certains navigateurs rechargent la page quoi qu'il arrivent, tandis que d'autres non. Apparament IE recharge, pas firefox.

Si ça se confirme pour firefox, alors c'est logique qu'il ne se passe rien si on tape #ancre" directement dans la barre d'adresse si on est déjà sur la page. Par contre ça devrait fonctionner correctement si on saisit l'URL avec l'ancre comprise si on était sur une autre page avant

Pour safari je ne sais pas, je n'ai pas de mac.
QuentinC a écrit :

Je réessaye une fois pour être sûr d'être bien clair, ce n'est pas toujours facile de bien expliquer du premier coup. L'idée est la suivante :
1. Au cas où js est désactivé ou indisponible, toutes les div doivent être visibles par défaut. Donc pas de display:none en dur en CSS


Bon, plus de doute, je dois les virer donc. Je ne me suis pas encore occupé du problème du JS désactivé mais dans ce cas, effectivement, vaut mieux ne pas mettre en CSS les div en hide. OK pour ça ! On retombe sur le problème que j'évoqué mais bon, parfois on n'a pas le temps de voir les div que l'on masque. De plus, priorité à l'accessibilité.

QuentinC a écrit :
2. Si le js est activé, le script se lance au chargement de la page
2.1. S'il y a une ancre, masquer toutes les div sauf celle qui est visée
2.2. S'il n'y a pas d'ancre, masquer toutes les div sauf celle qui représente la page d'accueil


Ok, c'est déjà fait.

QuentinC a écrit :
3. Au clic sur un lien d'une ancre
3.1. Dans certains navigateurs, la page se recharge; qu'il y ait script ou pas, la div visée n'a jamais été masquée donc le navigateur et les lecteurs d'écran vont sauter au bon endroit
3.2. Dans certains autres navigateurs, la page ne se recharge pas. Dans ce cas, il faut masquer la div précédemment affichée et montrer la nouvelle à la place.


En gros, c'est le navigateur qui à la main, donc je ne peux pas faire grand chose de plus, si je saisie bien.

QuentinC a écrit :
Ne pas return false dans le onclick pour permettre aux lecteurs d'écran de sauter au bon endroit quand même


Noté, d'ailleurs j'ai pris en compte cette recommandation dès ton premier post.

QuentinC a écrit :
Je prévois deux cas 3.1 et 3.2 parce qu'en fait, j'ai l'impression que certains navigateurs rechargent la page quoi qu'il arrivent, tandis que d'autres non. Apparament IE recharge, pas firefox.

Si ça se confirme pour firefox, alors c'est logique qu'il ne se passe rien si on tape #ancre&quot; directement dans la barre d'adresse si on est déjà sur la page. Par contre ça devrait fonctionner correctement si on saisit l'URL avec l'ancre comprise si on était sur une autre page avant

Pour safari je ne sais pas, je n'ai pas de mac.


Alors si tu entres l'adresse avec l'ancre, on voit le div demandé, ok.
Si tu as adresse#uneAncre et que tu change avec #uneAutreAncre, là ça ne fonctionne pas.
Mais vu se que tu dis, à priori, c'est normal.

Du coup je pense que c'est bon, mais je t'invite à tester le site que je reviendrais ici, ce week-end pour communiquer l'adresse et avoir vos retours Smiley smile
Enfin si tu as 5min.

Merci en tout cas pour ton aide, je vais récupérer ton texte pour le mettre de côté.
Modifié par MagicCarpet (20 Aug 2013 - 22:45)
a écrit :
Je ne me suis pas encore occupé du problème du JS désactivé mais dans ce cas, effectivement, vaut mieux ne pas mettre en CSS les div en hide. OK pour ça ! On retombe sur le problème que j'évoqué mais bon, parfois on n'a pas le temps de voir les div que l'on masque. De plus, priorité à l'accessibilité.

Merci. Normalement si ton site est suffisament bien fait, je ne pense pas que les div apparaissent assez longtemps pour gêner.

Mettre en display:none par défaut ne pose pas uniquement problème si js est désactivé, mais aussi potentiellement plus largement à tous les lecteurs d'écran.
Ils sont en effet en général plus rapides que tous les scripts js pour sauter à l'endroit adéquat. J'aurais tendance à dire que js, lent par définition par rapport à du natif C/C++/ObjC ne peut pas lutter. Problème: si le lecteur d'écran tente de sauter au bon endroit alors que le script d'affichage ne se serait pas encore exécuté, alors il n'y arrive pas puisque ce qu'il cherche est masqué.
Pire, tu ne peux pas prévoir qui du lecteur d'écran qui cherche l'ancre ou du script javascript qui l'affiche s'exécutera en premier, au cas improbable où js est ultra-rapide ou le lecteur plutôt lent. Donc il se pourrait même que ça devienne un problème intermittant.

a écrit :
En gros, c'est le navigateur qui à la main, donc je ne peux pas faire grand chose de plus, si je saisie bien.

Je n'ai jamais fait de vrai test pour le confirmer ou l'infirmer, mais j'en ai bien l'impression.

IL ne me semble pas qu'une quelconque norme régisse le fait ou non de recharger une page quand c'est juste l'ancre qui change. Et d'après moi, d'un point de vue technique et développement, les deux possibilités ont chacune leurs intérêts.
QuentinC a écrit :

Merci. Normalement si ton site est suffisament bien fait, je ne pense pas que les div apparaissent assez longtemps pour gêner.


Non se n'est pas vraiment gênant, c'est plutôt le point de vue "esthétique" que je voulais soigner mais bon, avec le web on fais pas toujours se qu'on veut. Sur une App je n'aurais pas laissé passer ce détail.

QuentinC a écrit :
Mettre en display:none par défaut ne pose pas uniquement problème si js est désactivé, mais aussi potentiellement plus largement à tous les lecteurs d'écran.
Ils sont en effet en général plus rapides que tous les scripts js pour sauter à l'endroit adéquat. J'aurais tendance à dire que js, lent par définition par rapport à du natif C/C++/ObjC ne peut pas lutter. Problème: si le lecteur d'écran tente de sauter au bon endroit alors que le script d'affichage ne se serait pas encore exécuté, alors il n'y arrive pas puisque ce qu'il cherche est masqué.
Pire, tu ne peux pas prévoir qui du lecteur d'écran qui cherche l'ancre ou du script javascript qui l'affiche s'exécutera en premier, au cas improbable où js est ultra-rapide ou le lecteur plutôt lent. Donc il se pourrait même que ça devienne un problème intermittent.


D'ailleurs, c'est quoi un lecteur d'écran précisément ?

QuentinC a écrit :
Je n'ai jamais fait de vrai test pour le confirmer ou l'infirmer, mais j'en ai bien l'impression.


Je veux bien un retour à l'occasion Smiley smile

QuentinC a écrit :
IL ne me semble pas qu'une quelconque norme régisse le fait ou non de recharger une page quand c'est juste l'ancre qui change. Et d'après moi, d'un point de vue technique et développement, les deux possibilités ont chacune leurs intérêts.


Tout à fais d'accord.
a écrit :
c'est plutôt le point de vue "esthétique" que je voulais soigner mais bon, avec le web on fais pas toujours se qu'on veut. Sur une App je n'aurais pas laissé passer ce détail.

JE le répète, si ton site est assez rapide, je ne pense pas que les div apparaissent assez longtemps pour gêner. C'est de l'ordre du dizième de seconde normalement, si tes pages ont une taille raisonnable. A toi de faire pour.

a écrit :
D'ailleurs, c'est quoi un lecteur d'écran précisément ?

Ce serait trop long de t'expliquer ici en détail, je te suggère de faire une recherche. En bref, c'est un logiciel qui me lit verbalement grâce à une synthèse vocale ce qui se trouve sous le curseur, et ça m'est indispensable car mes yeux ne fonctionnent pas.

Tu peux en essayer gratuitement si tu veux, ça te donnera une bonne idée de comment on perçoit un site web. Sous windows, NVDA est un logiciel libre, ou sinon jaws de freedom scientific en mode démo 40 minutes. Sous mac/iPhone/iPad/iPod, il y a voice over, et sur bureau gnome pour linux il y a orca.
Ta réponse me convient parfaitement, je vois se que c'est et je testerais à l'occasion.

Pour le point esthétique, j'ai bien compris mais je suis pointilleux Smiley smile

Bon, un dernier problème à résoudre, ça concerne ma page qui remonte dû aux ancres et le menu du haut qui lui, remonte aussi... J'en ai parlé plus haut, voici mes essais :
- le position fixed n'est pas viable (le bloc dépasse de la page, les ascenseurs ne sont pas présents, ça casse la mécanique du fluide).
- un margin-top ne résous évidemment pas le problème (je voulais quand même essayer)
- la solution pourrais venir du JS mais j'ai essayé plusieurs choses, ça ne fonctionne pas. Voici mon code qui affiche les div quand on clic sur un menu :

var $toggleTopBar = $('.toggle-topbar > a');
				var $toggleBarMenu = $('nav > section > ul > li');

				$toggleBarMenu.click(function() {
					$toggleTopBar.click();
				});

				$('nav > section > ul > li > a').click(function(e) {
					$this = $(this);

					// Coloration du menu
					$this.parent().siblings().removeClass('active');
					$which_Li = $this.parent().addClass('active');
					$hideMyDivs.removeClass('hide');

// Affichage des div
					var destination = $this.attr('href');
					var showMyDiv = destination.slice(1);
					$('#' + showMyDiv).siblings('article').addClass('hide');

					if($this.text() === 'gallery') {
						callGalleria();
					}

					$('body').scrollTop();
				});


Le scrollTop ne fonctionne pas. J'ai essayé avec un argument, j'ai essayé document à la place de body, j'ai aussi essayé d'autre code "pure" JS trouvé sur d'autres forums mais rien à faire.

EDIT : J'ai aussi essayé de "fixer" le menu mais même en lisant la doc de Foundation, je ne vois pas comment faire. Du moins, a un moment j'avais bien le menu en haut mais apparemment ils passent par un JS qui n'est pas très performant. Effectivement le menu est un peu "fluctuant". Il ne reste pas toujours vraiment à sa place. Bref, pas terrible. A ce niveau là, le Bootstrap de Twitter est bien meilleur.

Merci pour ton aide.
Modifié par MagicCarpet (21 Aug 2013 - 17:06)
Bon j'ai essayé pleins de trucs avec la fonction scrollTop() mais rien à faire. Quelqu'un n'aurais pas une solution ? En Js pur peut-être ? Ou m'expliquer cette méthode parce que je suis retourné sur la page jQuery mais je n'arrive pas à l'utiliser correctement.
Je ne peux plus t'aider là, il faudra demander à quelqu'un d'autre. Mes connaissances de CSS sont très partielles, et je n'utilise pas JQuery.

IL doit sûrement encore y avoir des vieux scripts émulant position:fixed pour IE5 qui traînent...
Zelalsan m'a donné la solution, je ne suis pas super satisfait mais encore une fois, le web à ses limites Smiley smile

La voici :

setTimeout(function(){
		window.scrollTo(0, 0);
	}, 10);


Sinon avec du CSS mais bon, je sais pas si c'est valable de se prendre la tête pour ça.

Une dernière choses, quand tu indique l'adresse www.mon-site.com il ne termine pas avec index.html. Du coup avec mes ancres j'ai quelque chose comme www.mon-site.com/#mon-ancre

Une petite idée ?
a écrit :

Une dernière choses, quand tu indique l'adresse www.mon-site.com il ne termine pas avec index.html. Du coup avec mes ancres j'ai quelque chose comme www.mon-site.com/#mon-ancre
Une petite idée ?


Ca te pose vraiment problème ?
Parce que c'est tout à fait valide comme URL, il n'y a aucun souci à se faire de ce côté-là.

Si ça te chagrine vraiment trop, tu peux regarder du côté des redirections apache... mais franchement je ne vois pas l'utilité.
Pages :