Bonjour !
Depuis plusieurs jours je parcours ouragans et tempêtes dans les terres arides qu'est le Web.
J'ai fais beaucoup de recherche pour faire un Breadcrumbs ( autrement dit Fil d'Ariane ) en JS.
Beaucoup sont codé côté serveur en PhP, mais mon but est de le faire uniquement en JS ( c'est beaucoup plus compliqué.. )
Après plusieurs recherches en vain..
Des collègues m'ont ( plus ou moins ) aidés en donnant une partie de code..... ( sans me donner d'explication )
N'étant pas très expérimenté en JS je vous laisse imaginer le charabia...

Toute fois j'essaye encore de décoder tout ça en vain..
En continuant mon étrange périple qui est de comprendre l'étendu de ce code.
Je voulais savoir si quelque uns d'entre vous pourriez m'éclaircir sur mon chemin !


function breadcrumbs() {
  sURL = new String;
  bits = new Object;
  var x = 0;
  var stop = 0;
  var output = "<div class=topnav><a href=/>home</a> » ";

  sURL = location.href;
  sURL = sURL.slice(8,sURL.length);
  chunkStart = sURL.indexOf("/");
  sURL = sURL.slice(chunkStart+1,sURL.length)

  while(!stop){
    chunkStart = sURL.indexOf("/");
    if (chunkStart != -1){
      bits[x] = sURL.slice(0,chunkStart)
      sURL = sURL.slice(chunkStart+1,sURL.length);
    } else {
      stop = 1;
    }
    x++;
  }

  for(var i in bits){
    output += "<a href=\"";
    for(y=1;y<x-i;y++){
      output += "../";
    }
    output += bits[i] + "/\">" + bits[i] + "</a> » ";
  }
  document.write(output + document.title);
  document.write("</div>");
  }


( Encore ça va j'ai a peux près compris cette partie )
Mais celle la... C'est de la magie ou je ne m'y connais pas !

Bibbidi-Bobbidi-Boo ! :


;( function( window ) {
	
	'use strict';

	var document = window.document;

	function extend( a, b ) {
		for( var key in b ) { 
			if( b.hasOwnProperty( key ) ) {
				a[key] = b[key];
			}
		}
		return a;
	}

	function cbpHorizontalSlideOutMenu( el, options ) {	
		this.el = el;
		this.options = extend( this.defaults, options );
		this._init();
	}
  
    // GetComputedStyle polyfill for IE8
    //  http://snipplr.com/view/13523/
 
    if (!window.getComputedStyle) {
        window.getComputedStyle = function(el, pseudo) {
            this.el = el;
            this.getPropertyValue = function(prop) {
                var re = /(\-([a-z]){1})/g;
                if (prop == 'float') prop = 'styleFloat';
                if (re.test(prop)) {
                    prop = prop.replace(re, function () {
                        return arguments[2].toUpperCase();
                    });
                }
                return el.currentStyle[prop] ? el.currentStyle[prop] : null;
            }
            return this;
        }
    }

	cbpHorizontalSlideOutMenu.prototype = {
		defaults: {},
		_init: function () {
			this.current = -1;
			this.touch = Modernizr.touch;
			this.menu = this.el.querySelector('.rte-menu');
			this.menuItems = this.el.querySelectorAll('.rte-menu > li:not(.user-menu)');
			this.menuBg = document.createElement('div');
			this.menuBg.className = 'rte-menubg';
			this.el.appendChild(this.menuBg);
			this._initEvents();
			this._initBreadcrumb();
		},
		_openMenu: function (el, ev) {

			var self = this,
				item = el.parentNode,
				items = Array.prototype.slice.call(this.menuItems),
				submenu = item.querySelector('.rte-submenu'),
				subsubmenu = item.querySelectorAll('.rte-sub-submenu'),
				activeHeight, // Stores the max height
							  // among the different <ul>s of the currently open menu.
							  // [submenu.height, subsubmenu[item1].heigth, ..., subsubmenu[itemN].heigth]
				closeCurrent = function (current) {
					var current = current || self.menuItems[self.current];
					current.className = '';
					current.setAttribute('data-open', '');
				},
				closePanel = function () {
					self.current = -1;
					self.menuBg.style.height = '0px';
				};

			if (submenu) {

				ev.preventDefault();

				/*if (item.getAttribute('data-open') === 'open') {
					closeCurrent(item);
					closePanel();
				}
				else {*/
					item.setAttribute('data-open', 'open');
					if (self.current !== -1) {
						closeCurrent();
					}
					self.current = items.indexOf(item);
					item.className = 'cbp-hsitem-open';
					// Use dynamic Height of the current active menu
					// Active Submenu height (level 2)
					activeHeight = submenu.clientHeight;
					// Get paddings of active submenu (level 2) to add them to active submenu (level 3)
					var paddingTop = window.getComputedStyle(submenu, "").getPropertyValue('padding-top');
					var paddingBottom = window.getComputedStyle(submenu, "").getPropertyValue('padding-bottom');
					var paddings = +paddingTop.split('px')[0] + +paddingBottom.split('px')[0];
					// Active submenu height (level 3)
					// Store maximum height to set height of the bg menu element
					[].forEach.call(subsubmenu, function (el) {
						activeHeight = Math.max(activeHeight, el.clientHeight + paddings);
					});

					self.menuBg.style.height = activeHeight + 'px';
				//}
			}
			else {
				if (self.current !== -1) {
					closeCurrent();
					closePanel();
				}
			}

		},
		_initEvents: function () {

			var self = this;

			Array.prototype.slice.call(this.menuItems).forEach(function (el, i) {
				var trigger = el.querySelector('a');

				// Listeners for menu elements.
				if (self.touch) {
					trigger.addEventListener('touchstart', function (ev) {
						self._openMenu(this, ev);
					});
					trigger.addEventListener('open', function (ev) {
						self._openMenu(this, ev);
					});
				}
				else {
					trigger.addEventListener('click', function (ev) {
						self._openMenu(this, ev);
					});
					trigger.addEventListener('open', function (ev) {
						self._openMenu(this, ev);
					});
				}
			});

			window.addEventListener('resize', function (ev) {
				self._resizeHandler();
			});

		},

		_initBreadcrumb: function () {

			var self = this;

			var breadcrumbs_trigger = document.querySelectorAll("nav.breadcrumb a[data-link]");

			Array.prototype.slice.call(breadcrumbs_trigger).forEach(function (el, i) {
				// Listeners for menu elements.
				if (self.touch) {
					el.addEventListener('touchstart', function (ev) {
						var elem = document.querySelector('.rte-menu li a[data-link="' + link + '"]');

						self._getParentDataLinks(elem);


						self._openMenu(elem, ev);
					}, false);
				}
				else {
					el.addEventListener('click', function (ev) {
						ev.preventDefault();
						var clicked_link = this;
						// Loop over all elements until this one to open then
						for (var i = 0; breadcrumbs_trigger.length; i++) {
							var el = breadcrumbs_trigger[i];
							var link = el.getAttribute("data-link");
							// Get the corresponding rte-menu element.
							var rte_elem = document.querySelector('.rte-menu li a[data-link="' + link + '"]');
							// Open this element.
							self._eventFire(rte_elem, 'open');
							// Stop at current element.
							if (el == clicked_link) {
								break;
							}
						}
					}, false);
				}
			});

			window.addEventListener('resize', function (ev) {
				self._resizeHandler();
			});

		},
		_resizeHandler: function () {
			var self = this;

			function delayed() {
				self._resize();
				self._resizeTimeout = null;
			}

			if (this._resizeTimeout) {
				clearTimeout(this._resizeTimeout);
			}

			this._resizeTimeout = setTimeout(delayed, 50);
		},
		_resize: function () {
			if (this.current !== -1) {
				this.menuBg.style.height = this.menuItems[this.current].querySelector('.rte-submenu').offsetHeight + 'px';
			}
		},

		_eventFire: function(el, etype) {
			if (el.fireEvent) {
				el.fireEvent('on' + etype);
			} else {
				var evObj = document.createEvent('Events');
				evObj.initEvent(etype, true, false);
				el.dispatchEvent(evObj);
			}
		}
	};

	// add to global namespace
	window.cbpHorizontalSlideOutMenu = cbpHorizontalSlideOutMenu;

} )( window );



Merci à ceux qui pourront m'aider,
Bon week end ! Smiley jap [/i][/i][/i]
Modifié par Golderen (02 Dec 2016 - 10:32)
Modérateur
Bonjour, le premier décompose l'url pour créer un breadcrumb (statique) :

Par exemple sur l'url : http://www.alsacreations.com/article/lire/1205-outils-integration-web-debuter.html
il créera le bredcrumb suivant:

home » article » lire » Les bons outils pour commencer à intégrer votre site web - Alsacreations

Ce qui est le mieux que l'on puisse faire en javascript, mais qui n'est pas terrible (ici lire produit une 404) il faut penser les url en accord avec cela.
On pourrait améliorer en intérogeant le serveur en ajax (mais du coup pourquoi ne pas faire le breadcrumb côté serveur? )
Ou si le site est full ajax, là les choses deviennent différentes.



Le second n'a rien avoir et est pour gérer un type de menu (il vient de là : http://tympanus.net/codrops/2013/05/17/horizontal-slide-out-menu )
Modifié par kustolovic (02 Dec 2016 - 10:51)
Modérateur
Sinon pour un breadcrumb historique, on peut imaginer jouer avec le stockage local (localStorage, sessionStorage ou même des cookies)

On pourrait aussi imaginer rechercher la page courante dans un menu.

Mais tout cela dépend beaucoup de la nature et de la structure du site.
Merci pour l'explication Smiley smile

Effectivement j'avais a peux près compris le premier fragment de code mais c'étais le deuxième que je ne comprenais absolument pas et que je croyais utile pour le breadcrumb..

Concernant le site je veux le faire uniquement HTML / CSS / JS sans côté serveur justement ^^
Et pour le site il est structurer de la manière suivante :

( l'item avec le " - " est la page sur laquelle nous sommes, ceux en dessous sont les liens vers les autres pages )

- Index
menu 1
menu 2
menu 3
menu 4
_________

- menu1
sousmenu1-1
sousmenu1-2
sousmenu1-3
menu4
__________

- menu2
sousmenu2-1
sousmenu2-2
sousmenu2-3
menu4
___________

- menu 3
menu 1
menu 2
menu 3
menu 4

( pareil pour menu 4 )

Voila,
Après j'avais effectivement trouvé des morceaux de code où des personnes qui expliqué comment récupérer la page actuelle avec les cookies comme tu le cite
Mais je trouve sa encore beaucoup trop compliqué pour mon niveau ^^"
Bonjour Golderen,
s'il te fallait juste créer un menu, le css3 (avec effets de transition sympas et opérationnels sur de multiples liens !) est très facile à mettre en oeuvre ...

Qui a osé prétendre que le css3 refusait de multiples liens cliquables dans un menu ? Et que le html aménagé (par js) ne renseignerait pas la page-en-cours ?
Modifié par pictural (02 Dec 2016 - 13:26)
a écrit :
s'il te fallait juste créer un menu, le css3 (avec effets de transition sympas et opérationnels sur de multiples liens !) sont très faciles à mettre en oeuvre ...


C'est pas le but de ce topic, j'ai déjà un menu c'est pas le problème ! ^^

C'est juste que Kustolovic me demandé comment était structuré le site.

Personne ne prétend cela tu as du te trompé Pictural Smiley hippy
a écrit :
Et que le le html aménagé ne renseignerait pas la page-en-cours ?

Est ce que tu peux développer s'il te plait ? ^^
@Golderen,
je crains de ne pas tout comprendre, en effet.

Donc je me retire, humblement.
Modifié par pictural (02 Dec 2016 - 13:30)
Modérateur
Il faut déjà déterminer ce que tu veux comme breadcrumb,

Un breadcrumb hiérarchique, qui liste la hiérarchie jusqu'à la page. (sera toujours le même sur une page)
Un breadcrumb historique, qui liste l'historique des pages parcourues.

Pour le second, il faudra effectivement écrire un code qui stocke les pages au fur et à mesure de la navigation

Pour le premier, ton premier code peut parfaitement convenir pourvu que tu aies un index dans chaque dossier et sous-dossier et que les dossiers portent des noms acceptables.

Tu peux aussi les faire à la main dans chaque page.

Tu peux aussi te dire qu'un breadcrumb hiérarchique ne sert à rien sur une structure si simple, et qu'un breadcrumb historique n'apporte rien en plus de l'historique du navigateur.
C'est effectivement un breadcrumb hiérarchique que je veux faire.
Pour l'instant j'en ai un fixe sur chaque page mais sa serait plus simple ( et plus dur a la fois dans un sens ) que je fasse une fonction qui justement rajoute a chaque fois dans la liste a quelle page nous sommes au lieux de le remplir manuellement a chaque page html.

Dans un sens je pourrais m'en passer mais c'est que je vais avoir deux catégories et dans ses deux catégories l'utilisateur vas retrouver deux fois le même intitulé " présentation " Mais qui n'est pas dans la même hiérarchie.
Je m'explique :
Catégorie Lignard :
il y aura :
présentation, spécification ect..

et dans la catégorie Post :
il y aura une autre catégorie :
Présentation, spécification ect..

C'est pour pas que l'utilisateur ce perde dans le site

En gros sa feras :

Accueil > Lignard > Présentation
ou si dans Post :
Accueil > Post > Présentation
Modérateur
Golderen a écrit :

Pour l'instant j'en ai un fixe sur chaque page mais sa serait plus simple ( et plus dur a la fois dans un sens ) que je fasse une fonction qui justement rajoute a chaque fois dans la liste a quelle page nous sommes au lieux de le remplir manuellement a chaque page html.

Bien entendu, mais c'est précisément pour ce genre de choses que l'on utilise un langage serveur. C'est un peu étrange de vouloir construire toutes ses pages manuellement excepté un élément, et vouloir le construire avec un langage qui ne s'y adapte pas. Comment sont fait les menus? Lorsque le menu change, il faut le modifier sur toutes les pages?
Oui les menus sont différents par pages, mais au final je pense que je vais laisser le breadcrumb en dur par page sa seras plus simple ^^
@Golderen,
s'il m'était permis de comprendre finalement ce que tu souhaites, je te dirais que ton envie est excellente.

Une solution facile à mettre en œuvre serait :
1. de créer un menu "en dur"
2. de l'aménager de page en page pour la page-en-cours par javascript : 4 ou 5 lignes de script placées juste avant </body> rectifieront les contenus .html .css3 des éléments visés précisément par la page-en-cours ...

Non ?
Modifié par pictural (04 Dec 2016 - 20:59)
@Golderen,
en tout cas c'est ce que j'ai pratiqué ici (pour un projet de site web d'artisans) :
http://sentrais.eu/chinon-art/index.htm
(lire le code-source de chaque page, et un .js près le </body> aménagé pour chaque page)
et je crois savoir que nous sommes nombreux à pratiquer d'une telle sorte ...

Bref ! une infime rectification du .html et .css menée par .js sera judicieuse, meilleure encore que je ne l'ai pratiquée.

Et selon que je te comprenne : pas besoin de .php
Modifié par pictural (06 Dec 2016 - 12:31)
Merci Pictural pour ta réponse Smiley smile
Au final je pense que je vais laissez cette idée de côté et la reprendre une fois que j'aurais acquis de plus ample connaissance sur JS ^^
Je vais garder la liste en dur et retravaillerais dessus plus tard Smiley smile