Partage
  • Partager sur Facebook
  • Partager sur Twitter

rafraîchir une variable

    29 décembre 2008 à 11:29:39

    bonjour amis Zér0s,

    Je pose certainement une question basique mais, quelque soit la manière dont je la formule, Google ne veut rien me dire d'intéressant. J'utilise ce bout de script pour calculer la taille d'un div en fonction de la taille de la fenêtre (je ne peux malheureusement pas le faire en CSS) :

    if (document.body)
    {
    var largeur = (document.body.clientWidth);
    }
    else
    {
    var largeur = (window.innerWidth);
    }
    var largeurdudiv = largeur -530;
    


    ça marche impec, je voudrais simplement actualiser ma variable largeurdudiv quand l'utilisateur redimensionne la fenêtre afin que ses nouveaux paramètres d'affichage soient pris en compte. Bref, c'est pour un design flexible.

    Comment dois-je faire dans les grandes lignes ? pouvez-vous me diriger vers un tuto ? Est-ce que ce n'est pas trop lourd de recalculer continuellement (et peut-être inutilisement) la largeur de ce div ? J'ai déjà pas mal de trucs graphiques en js sur ma page..

    Merci pour votre aide et vos conseils.
    • Partager sur Facebook
    • Partager sur Twitter
      29 décembre 2008 à 13:19:19

      Beh il n'y a pas d'événement déclenché lors du resize de la fenêtre, donc il faut appeler une fonction à un intervalle régulier qui le recalculera.
      Ou alors tu te débrouille en css pour faire des marges et des tailles en % ;) .
      • Partager sur Facebook
      • Partager sur Twitter
        29 décembre 2008 à 13:27:02

        Salut,

        @Timot: C'est dingue, j'aurais pourtant juré que l'évènement onresize existait! o_O
        Mais bon, je dois me tromper et w3school aussi...

        ps: On se renseigne avant de dire des bêtises.
        • Partager sur Facebook
        • Partager sur Twitter
          29 décembre 2008 à 13:34:53

          Zioup, j'été pérsuadé qu'il existait pas. Est il compatible sur tous les navigateurs ?
          Cependant, j'ai remarqué qu'il n'interceptais l'événement que lorqu'on arrétais de resize la fenêtre. Donc pendant le resize, on ne peux pas capter d'événement. Donc ce que je disais n'étais pas totalement faux ;) .
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            29 décembre 2008 à 13:44:08

            ( edit ) Sur IE c'est comme ça, FF lance l'évènement tout le temps (un peu trop meme… ça peut faire rammer a cause de ça…)

            http://www.quirksmode.org/dom/events/resize.html

            var tailleDiv = function () {
                // ici on garde l'élément HTML en mémoire ça coute
                // cher d'aller le rechercher à chaque fois. C'est le
                // principe de la "closure".
                var TonDiv = document.getElementById("hop");
                // on initialise le truc la première fois que l'on appelle la fonction
                TonDiv.style.width = ((document.body ? 
                            document.body.clientWidth : 
                            window.innerWidth) - 530) +"px"
                // et on renvoie une fonction qui a accès a la variable TonDiv
                return function () {
                    // je suppose que c'est ce que tu veux faire
                    TonDiv.style.width = ((document.body ? 
                            document.body.clientWidth : 
                            window.innerWidth) - 530) +"px";
                    };
            };
            // IE appelle resize au chargement, quand le html n'est pas forcement chargé
            // c'est pas impossible qu'il y ait des problèmes. si il y en a met ça dans
            // le onload de window.
            window.onresize = tailleDiv();
            

            Si tu mets ton javascript tout à la fin de ton code html (juste avant <body>) – comme il est recomandé – il n'y aura pas de problèmes.
            • Partager sur Facebook
            • Partager sur Twitter
              29 décembre 2008 à 15:06:32

              Bonjour et merci pour vos réponses. En fait j'utiliserais ça dans un script de menu "accordéon" qui fait appel à une librairie.

              Il laisse le choix de définir une taille en pixels ou de laisser le div s'adapter au contenu (valeur null). Or je n'arrive pas en CSS à le rendre flexible : les dimensions en pourcentages déconnent avec ce script et je n'ose pas mettre les mains dans le code de l'auteur (pas le niveau !).

              D'où l'idée de donner des dimensions en Javascript. Je vais voir comment je peux intégrer ce que vous m'avez passé. Je vois que vous modifiez les propriétés CSS du div et ce n'est pas ce que j'attendais (j'en attendais beaucoup moins, merci :lol: ). Donc si j'ai bien compris c'est l'évènement window.onresize qui va relancer le calcul pour actualiser la taille ?

              voici le code dans lequel la variable doit s'inscrire.
              Event.observe(window, 'load', loadAccordions, false);
              
              function loadAccordions() {
              var menuAccordion = new accordion('menu_container', {
              	classNames :  {
              		toggle : 'menu_accordion_toggle',
              		toggleActive : 'menu_accordion_toggle_active',
              		content : 'menu_accordion_content'
              		      },
              	defaultSize : {
              		width : xxx // c'est là que j'utilise largeurdudiv
              	              },
              	direction : 'horizontal'
              });		
              
              }
              
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                29 décembre 2008 à 15:29:55

                Oui mais non, si tu met une variable qui change il s'en fout le script. Lui il a besoin de la valeur quand il est crée, il se met pas a jour quand la variable change de valeur.

                Il faut que tu modifie la largeur directement ou que tu trouves comment faire en css
                • Partager sur Facebook
                • Partager sur Twitter
                  29 décembre 2008 à 15:36:47

                  Arf ! Mais ta méthode marche quand même non ? Je dois filer, je regarderai ça plus attentivement et vous donnerai des nouvelles.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    29 décembre 2008 à 16:20:47

                    si t'as l'id de l'élement qui contient le menu ça devrait marcher, il faut le script complet pour etre sur
                    • Partager sur Facebook
                    • Partager sur Twitter
                      29 décembre 2008 à 23:31:33

                      Buarf, c'est plus compliqué que je ne pensais.

                      Déjà, je me suis rendu compte que je devais appliquer l'effet non pas à un div mais à plusieurs (les différents conteneurs de l'accordéon) donc je dois utiliser des classes. Là, pour dépanner, j'ai copié trois fois ton script avec des ID différents :p mais je sais que ça va être le bordel pour cibler une classe (il n'y a pas de getElementByClass en JS il me semble).

                      En suite, bien que le script fonctionne, dès que je referme un onglet de l'accordéon ce dernier oublie quelle taille il avait lors du dernier resize et reprend sa taille d'origine. Les autres onglets n'ayant pas été redimensionnés n'ont pas non-plus connaissance de la modification. J'ai essayé de les réveiller avec un onclick mais apparemment ça ne fonctionne pas (je m'y prend peut-être mal).

                      Enfin, je n'arrive pas à utiliser ton script avec window.onresize : bizarrement ça ne fonctionne pas sur firefox. J'ai essayé avec un <body onresize=""> et ça marche, mais ce n'est pas valide et je ne sais pas si c'est compatible.

                      La page est visible ici.

                      Dire que si j'avais fait ça en flash ce serait passé comme une lettre à la poste !
                      • Partager sur Facebook
                      • Partager sur Twitter
                        29 décembre 2008 à 23:34:52

                        getElementsByClassName("nom_de_la_classe") est disponible avec Firefox 3. Mais pour IE, possible que ça plante.

                        La solution reste de parcourir tous les div, et de vérifier la class...
                        • Partager sur Facebook
                        • Partager sur Twitter
                          30 décembre 2008 à 17:07:06

                          J'ai un gros souci de compatibilité sur IE pour mes dimensions : il ne les prend pas.

                          J'ai fait un alert(); pour voir ce qu'il me rendait et effectivement il ne rend rien, enfin il me dit "NaN" ("Not a Number" ? ) et quand je lui demande document.body.clientWidth il me répond "undefined" (oui, je parle avec mon navigateur, ça dérange quelqu'un ?! :p ). Ces tests sont effectués sur un onclick et sur un onload, j'ai même fait le test en supprimant tout code de ma page et rien n'y fait, pourtant c'est une écriture éprouvée, non ?

                          J'ai lu que document.body.clientWidth ne fonctionnait que quand la page était chargée, est-ce que ça pourrait venir de là ? mais même dans ce cas la fonction tailleDiv() devrait fonctionner or ce n'est pas le cas, et ça n'explique pas le résultat de mes tests.

                          :(
                          • Partager sur Facebook
                          • Partager sur Twitter
                            30 décembre 2008 à 17:40:49

                            Citation : Golmote

                            getElementsByClassName("nom_de_la_classe") est disponible avec Firefox 3. Mais pour IE, possible que ça plante.

                            La solution reste de parcourir tous les div, et de vérifier la class...


                            je conseil vivement cette focntion... elle disponible(d'après mes tests et le site sur lequelle je l'ai gracieusement copiée) sur tous les navigateurs
                            function cstmGetElementsByClassNameExt(parentElement, class_name, tag) {
                                /* Extendeds function with performance improvements.
                                 * by using a parentElement and the tag the class is on
                                 * the list of elements to check is reduced.
                                 *
                                 * This function doesn't get bound to an object.
                                 */
                                var docList;
                                var matchArray;
                                var re;
                                var len;
                                
                                tag = tag || "*";
                                parentElement = parentElement || document;
                                if (typeof parentElement == "string") //object could be passed instead of Id
                                    parentElement = document.getElementById(parentElement);
                                    
                                /* Get array of tags */
                                if (tag == "*") {
                                   /* The test is to accommodate IE 5, 
                                    * leave it out if IE 5 support is not required 
                                    */
                                   docList = parentElement.all || parentElement.getElementsByTagName('*');
                                } else {
                                   docList = parentElement.getElementsByTagName(tag);
                                }
                            
                                /*Create a regular expression object for class*/
                                re = new RegExp("(?:^|\\s)" + class_name + "(?:\\s|$)");
                            
                            	/* Create output array*/
                                matchArray = new Array();
                                len = docList.length;
                                
                                /* Populate output array from tag array 
                                 * do loop is faster than for loop 
                                 * albeit out is in reverse order
                                 */
                                while (len--) {
                                    if (re.test(docList[len].className)) {            
                                        matchArray[matchArray.length] = docList[len];
                                    }
                                }
                                //return matchArray.reverse(); //if the order needs to forward
                                return matchArray;
                            }
                            
                            • Partager sur Facebook
                            • Partager sur Twitter
                              30 décembre 2008 à 17:58:11

                              Waw, je trouve ça un peu compliqué pour ce que ça fait, surtout que je ne veux appliquer l'effet qu'à 3 divs. Est-ce que c'est plus rapide d'exécution ?

                              Par contre je vais améliorer mon bricolage qui ici ne servait qu'à me débarrasser temporairement du problème (la compatibilité sur IE étant... critique !).

                              Mais merci :D
                              • Partager sur Facebook
                              • Partager sur Twitter
                                30 décembre 2008 à 18:15:09

                                c'eest que j'ai copié la version complete... si tu veux je retrouve le site...; ils avaient aussi une version qui se contrefou des tagname... en 20 lignes a peu pres...
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  30 décembre 2008 à 18:33:56

                                  Ah, je vais chercher moi-même dans ce cas, ne t'embête pas.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    30 décembre 2008 à 18:42:16

                                    j'ai retrouvé

                                    http://www.robertnyman.com/2005/11/07/ [...] sbyclassname/

                                    tu copie la version pas deluxe et ca devrait etre bon :p
                                    mais la version que j'ai prise marche pareil... si on met pas de 3eme argument..

                                    ou sinon
                                    http://lawrence.ecorp.net/inet/samples [...] assname.shtml

                                    le 2eme permet de faire la manip directement depuis le document(document.getElementByTruk) alors que l'autre est utilisé comme une focntion avec document comme argument... mais bon la 1ere est moin compliqué je trouve :p
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      31 décembre 2008 à 0:30:41

                                      Des nouvelles du front : apparemment les scripts sont en conflit avec celui de l'accordéon !

                                      Je perçois comme des hésitations quand j'essaie de forcer la taille d'un div sur un évènement, ça explique pourquoi les divs reprennent toujours leur taille initiale et aussi pourquoi le rendu n'est pas toujours très propre.

                                      Je vais devoir plonger dan sle code initial, ça fait peur o_O
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        31 décembre 2008 à 17:19:50

                                        euh... elle devraient jamais reprendre leur taille si tu leur dit pas...

                                        montre ton code....
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          31 décembre 2008 à 19:00:04

                                          Tout est dispo en ligne, mais voici le js complêt des accordéons. Je n'ai que ce problème de resize, si non c'est plutôt satisfaisant. On pourrait améliorer le script en faisant se fermer les slides du menu quand on ouvre celui des news et j'ai un problème avec IE sur un accordéon vertical.

                                          if (typeof Effect == 'undefined') 
                                          	throw("accordion.js requires including script.aculo.us' effects.js library!");
                                          
                                          var accordion = Class.create();
                                          accordion.prototype = {
                                          
                                          	//
                                          	//  Setup the Variables
                                          	//
                                          	showAccordion : null,
                                          	currentAccordion : null,
                                          	duration : null,
                                          	effects : [],
                                          	animating : false,
                                          	
                                          	//  
                                          	//  Initialize the accordions
                                          	//
                                          	initialize: function(container, options) {
                                          	  if (!$(container)) {
                                          	    throw(container+" doesn't exist!");
                                          	    return false;
                                          	  }
                                          	  
                                          		this.options = Object.extend({
                                          			resizeSpeed : 8,
                                          			classNames : {
                                          				toggle : 'accordion_toggle',
                                          				toggleActive : 'accordion_toggle_active',
                                          				content : 'accordion_content'
                                          			},
                                          			defaultSize : {
                                          				height : null,
                                          				width : null
                                          			},
                                          			direction : 'vertical',
                                          			onEvent : 'click'
                                          		}, options || {});
                                          		
                                          		this.duration = ((11-this.options.resizeSpeed)*0.15);
                                          
                                          		var accordions = $$('#'+container+' .'+this.options.classNames.toggle);
                                          		accordions.each(function(accordion) {
                                          			Event.observe(accordion, this.options.onEvent, this.activate.bind(this, accordion), false);
                                          			if (this.options.onEvent == 'click') {
                                          			  accordion.onclick = function() {return false;};
                                          			}
                                          			
                                          			if (this.options.direction == 'horizontal') {
                                          				var options = $H({width: '0px'});
                                          			} else {
                                          				var options = $H({height: '0px'});			
                                          			}
                                          			options.merge({display: 'none'});			
                                          			
                                          			this.currentAccordion = $(accordion.next(0)).setStyle(options);			
                                          		}.bind(this));
                                          	},
                                          	
                                          	//
                                          	//  Activate an accordion
                                          	//
                                          	activate : function(accordion) {
                                          		if (this.animating) {
                                          			return false;
                                          		}
                                          		
                                          		this.effects = [];
                                          	
                                          		this.currentAccordion = $(accordion.next(0));
                                          		this.currentAccordion.setStyle({
                                          			display: 'block'
                                          		});		
                                          		
                                          		this.currentAccordion.previous(0).addClassName(this.options.classNames.toggleActive);
                                          
                                          		if (this.options.direction == 'horizontal') {
                                          			this.scaling = $H({
                                          				scaleX: true,
                                          				scaleY: false
                                          			});
                                          		} else {
                                          			this.scaling = $H({
                                          				scaleX: false,
                                          				scaleY: true
                                          			});			
                                          		}
                                          			
                                          		if (this.currentAccordion == this.showAccordion) {
                                          		  this.deactivate();
                                          		} else {
                                          		  this._handleAccordion();
                                          		}
                                          	},
                                          	// 
                                          	// Deactivate an active accordion
                                          	//
                                          	deactivate : function() {
                                          		var options = $H({
                                          		  duration: this.duration,
                                          			scaleContent: false,
                                          			transition: Effect.Transitions.sinoidal,
                                          			queue: {
                                          				position: 'end', 
                                          				scope: 'accordionAnimation'
                                          			},
                                          			scaleMode: { 
                                          				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
                                          				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
                                          			},
                                          			afterFinish: function() {
                                          				this.showAccordion.setStyle({
                                                    height: '100%',
                                          					display: 'none'
                                          				});				
                                          				this.showAccordion = null;
                                          				this.animating = false;
                                          			}.bind(this)
                                          		});    
                                              options.merge(this.scaling);
                                          
                                              this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);
                                              
                                          		new Effect.Scale(this.showAccordion, 0, options);
                                          	},
                                          
                                            //
                                            // Handle the open/close actions of the accordion
                                            //
                                          	_handleAccordion : function() {
                                          		var options = $H({
                                          			sync: true,
                                          			scaleFrom: 0,
                                          			scaleContent: false,
                                          			transition: Effect.Transitions.sinoidal,
                                          			scaleMode: { 
                                          				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentAccordion.scrollHeight,
                                          				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentAccordion.scrollWidth
                                          			}
                                          		});
                                          		options.merge(this.scaling);
                                          		
                                          		this.effects.push(
                                          			new Effect.Scale(this.currentAccordion, 100, options)
                                          		);
                                          
                                          		if (this.showAccordion) {
                                          			this.showAccordion.previous(0).removeClassName(this.options.classNames.toggleActive);
                                          			
                                          			options = $H({
                                          				sync: true,
                                          				scaleContent: false,
                                          				transition: Effect.Transitions.sinoidal
                                          			});
                                          			options.merge(this.scaling);
                                          			
                                          			this.effects.push(
                                          				new Effect.Scale(this.showAccordion, 0, options)
                                          			);				
                                          		}
                                          		
                                              new Effect.Parallel(this.effects, {
                                          			duration: this.duration, 
                                          			queue: {
                                          				position: 'end', 
                                          				scope: 'accordionAnimation'
                                          			},
                                          			beforeStart: function() {
                                          				this.animating = true;
                                          			}.bind(this),
                                          			afterFinish: function() {
                                          				if (this.showAccordion) {
                                          					this.showAccordion.setStyle({
                                          						display: 'none'
                                          					});				
                                          				}
                                          				$(this.currentAccordion).setStyle({
                                          				  height: '100%'
                                          				});
                                          				this.showAccordion = this.currentAccordion;
                                          				this.animating = false;
                                          			}.bind(this)
                                          		});
                                          	}
                                          }
                                          
                                          /////////////////////////////////////	C'est là que j'initialise mes accordéons
                                          	
                                          
                                          		//  load  onload
                                          		Event.observe(window, 'load', loadAccordions, false);
                                          
                                          		//	Set up accordions
                                          		function loadAccordions() {
                                          
                                          /////////////////////////////////////	C'est celui là qui a besoin d'être flexible
                                          
                                          			var menuAccordion = new accordion('menu_container', {
                                          				classNames : {
                                          					toggle : 'menu_accordion_toggle',
                                          					toggleActive : 'menu_accordion_toggle_active',
                                          					content : 'menu_accordion_content'
                                          				},
                                          				defaultSize : {
                                          					width : document.body.clientWidth - 140 - document.body.clientWidth / 3.3 
                                          // j'ai finalement utilisé l'écriture IE uniquement (qui fonctionne ici) car elle est compatible avec les autres navigateurs et que toute autre écriture renvoyait "NaN"
                                          				},
                                          				direction : 'horizontal'
                                          			});
                                          
                                          /////////////////////////////////////	ce sont d'autres accordéons qui n'ont rien à voir
                                          
                                          			var newsAccordion = new accordion('news_container', {
                                          				classNames : {
                                          					toggle : 'menu_accordion_toggle',
                                          					toggleActive : 'menu_accordion_toggle_active',
                                          					content : 'menu_accordion_content'
                                          				},
                                          				defaultSize : {
                                          					width : null
                                          				},
                                          				direction : 'horizontal'
                                          			});
                                          			
                                          			var compAccordion = new accordion('container', {
                                          				classNames : {
                                          					toggle : 'accordion_toggle',
                                          					toggleActive : 'accordion_toggle_active',
                                          					content : 'accordion_content'
                                          				},
                                          				defaultSize : {
                                          					height : null
                                          				},
                                          				direction : 'vertical'
                                          			});
                                          
                                          /////////////////////////////////////	ouverture automatique d'un des accordéons et optimisation du chargement de la page
                                          			
                                          compAccordion.activate($$('#container .accordion_toggle')[0]);
                                          			
                                          var menuAccordion = $$('.menu_accordion_toggle');
                                          horizontalAccordions.each(function(accordion) {
                                              $(accordion.next(0)).setStyle({
                                                  width: '0px'
                                              });
                                          });
                                          		}
                                          


                                          Sur cette version du code j'ai carrément viré le script de _nod parce que j'ai compris (il aura fallu le temps) que c'est sur le script initial qu'il faut bouger quelque chose, par contre je n'arrive pas à voir où.

                                          Pour le HTML je vous montre uniquement la structure parce que c'est assez touffu :D

                                          <div id="menu2"> <!-- height: 100%; overflow: hidden; -->
                                               <div id="menu_container" >  <!-- height: 80%; width: 100%; -->
                                          
                                                    <h3 class="menu_accordion_toggle">image</h3>
                                                    <div class="menu_accordion_content"> <!-- overflow: hidden; width: 100%; height: 100%; float: left; -->
                                                         <div id="content1">.......</div> <!-- width: 80%; height: 80%; margin: auto; overflow: auto; -->
                                                    </div>
                                          
                                                    <h3 class="menu_accordion_toggle">image</h3>
                                                    <div class="menu_accordion_content">
                                                         <div id="content1">.......</div>
                                                    </div>
                                          
                                                    <h3 class="menu_accordion_toggle">image</h3>
                                                    <div class="menu_accordion_content">
                                                         <div id="content1">.......</div>
                                                    </div>
                                          
                                               </div>
                                          </div>
                                          



                                          Un petit HS : je trouve que Opera lit vraiment super bien le JS, c'est fluide, c'est beau... bref, j'avais déjà remarqué qu'il intégrait (quasi) toujours bien le CSS, c'est incompréhensible qu'il ne soit pas plus populaire !
                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          rafraîchir une variable

                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                          • Editeur
                                          • Markdown