Partage

FOIRE AUX QUESTIONS - ANNEXE

Contribuez

8 octobre 2008 à 11:40:48

Bonjour,

Suite à la création de ce nouveau forum, j'ai donc transféré dans un nouveau sujet les questions concernant le javascript et ajax.

Comme ce que j'ai fait dans le forum php et html, je verrouille donc ce sujet et créé celui-ci dans l'optique de laisser une bonne lisibilité de la FAQ, pour ne pas la polluer avec des débats sur les futurs ajouts.

Ce sujet, servira donc aux membres qui le souhaitent, à proposer de nouveaux ajouts qui auraient une place dans cette FAQ.

Voilà, à vos propositions :)
8 octobre 2008 à 19:29:19

Mettre ce topic en Post-it ne serait-il pas un peu mieux ? Parce que là on ne le voit pas directement en arrivant sur le forum.

Concernant l'ajout de propositions, je verrai si j'ai quelque chose d'intéressant à proposer mais dans l'immédiat je n'ai aucune idée.

Edit : Nan, j'ai dit de la merde :-° .
12 octobre 2008 à 21:55:15

Des fonctions pour pouvoir modifier les feuilles de style dynamiquement.
En changeant le style d'une propriété d'un élément, on peut aussi juste récupérer le style sans le modifier.

/*############  Récupérer le style d'un élément  ##############*/
function RecupererStyle(nom_,document_) {
	var doc = ((document_)? document_ : this.document);
	var rules = doc.styleSheets[0].rules || doc.styleSheets[0].cssRules;
	
	for(var i=0; i<rules.length; i++) {
		if(rules[i].selectorText == nom_) 
			return rules[i].style;		
	}
	return null;
}


/*############  Changer le style d'un élément  ##############*/
function ChangerStyle(element_,propriete_,valeur_,importance_) {
	var propriete = (propriete_)?propriete_:"";
	var importance = (importance_)?importance_:"";
	var rules = RecupererStyle(element_);
	rules.setProperty(propriete,valeur_,importance)
}

Donc utilisation du genre :
RecupererStyle("#news") //Renvoie toutes les infos sur les propriétés de l'objet
ChangerStyle("#news","font-weight","bold") //Modifie le style font-weight de l'objet #news pour le mettre en bold

L'intérêt est bien sur pour des éléments autre que des ids. Pour changer de couleurs toutes les classe .classe, ou tous les éléments de tel type.

On peut largement les optimiser. Déjà, elle ne prend en compte que la premier feuille de style, il faudrait toutes les tester. Ensuite, pouvoir récupérer une seule propriété d'un élément, pouvoir en récupérer plusieurs, qu'on choisis, pouvoir en modifier plusieurs, ...
Je me pencherais sur l'optimisation a moins que quelqu'un d'autre veuille s'y aventurer ?
12 octobre 2008 à 22:00:21

Ton script m'interesse beaucoup mais j'ai trois feuilles de styles, donc comment faire pour que ton script les gérent toutes ?
12 octobre 2008 à 22:06:08

Euh, vite fais, je dirais un truc du genre :
/*############  Récupérer le style d'un élément  ##############*/
function RecupererStyle(nom_,document_) {
	var doc = ((document_)? document_ : this.document);
	for(var i=0; doc.styleSheets[i]; i++) {
		var rules = doc.styleSheets[i].rules || doc.styleSheets[i].cssRules;
	
		for(var i=0; i<rules.length; i++) {
			if(rules[i].selectorText == nom_) 
				return rules[i].style;		
		}
		return null;
	}
}

Par contre, tu ne peux pas reécrire le meme élement deux fois.
Du genre :
#news { color : blue; .... }
Et plus loin (ou dans une autre feuille) #news { color:black; ....}
Il te retourne que le premier.
D'ailleurs, il devrais plutot retourner seulement le dernier. Faudras l'optimiser ;) .
12 octobre 2008 à 22:12:30

:waw: Merci, ca me sera super utile ton truc ! je cherchais justement comment bien faire...
12 octobre 2008 à 22:38:56

Voila l'optimisation pour prendre que le dernier (plus logique) :
/*############  Récupérer le style d'un élément  ##############*/
function RecupererStyle(nom_,document_) {
	var doc = ((document_)? document_ : this.document);
	for(var i=doc.styleSheets.lenght; doc.styleSheets[i]; i--) {
		var rules = doc.styleSheets[i].rules || doc.styleSheets[i].cssRules;
	
		for(var i=0; i<rules.length; i++) {
			if(rules[i].selectorText == nom_) 
				return rules[i].style;		
		}
		return null;
	}
}



J'ai aussi une fonction pour qu'une iframe prenne toute la hauteur de son contenu :
/*#######  Pour que l'iframe prenne toute la hauteur  ##########*/
function PrendreHauteurMax(id_) {
	var iframe = document.getElementById(id_); 
	var content = iframe.contentWindow.document.body;
	iframe.style.height = content.scrollHeight+"px";
}




Une classe cookie :
/*############################################
##############   Classe cookie ######################
#############################################*/
	function Cookie(nom_,valeur_) {
		this.GetValue = LireCookie;
		this.SetValue = ModifierCookie;
		this.SaveCookie = EcrireCookie;
		this.ClearCookie = EffacerCookie;
		
		this.nom = nom_;
		this.value = (valeur_)? valeur_ : (this.GetValue() != null)? this.GetValue() : "";
	}

	function LireCookie() {
		var arg = this.nom + "=";
		var alen = arg.length;
		var clen = document.cookie.length;
		
		var i = 0;
		while (i < clen) {
			var j = i + alen;
			if (document.cookie.substring(i,j) == arg) {
				var endstr=document.cookie.indexOf (";", j);
				if (endstr==-1) 
					endstr=document.cookie.length;
				return unescape(document.cookie.substring(j, endstr));
			}
			i=document.cookie.indexOf(" ",i)+1;
			if (i==0) 
				break;
		}
		return null;
	}

	function ModifierCookie(value_) {
		this.value = value_;
		this.SaveCookie("full");
	}

	function EcrireCookie() {
		var argv = EcrireCookie.arguments;
		var argc = EcrireCookie.arguments.length;
		
		var expires = 	(argc > 0) ? argv[0] : null;
		var path = 		(argc > 1) ? argv[1] : null;
		var domain = 	(argc > 2) ? argv[2] : null;
		var secure = 	(argc > 3) ? argv[3] : false;
		
		if(expires == "full") {
			var date = new Date;
			date.setFullYear(date.getFullYear()+10);
			expires = date;
		}
		

		document.cookie=
			this.nom + "=" + escape(this.value)+
			((expires==null) ? "" : ("; expires="+expires.toGMTString()))+
			((path==null) ? "" : ("; path="+path))+
			((domain==null) ? "" : ("; domain="+domain))+
			((secure==true) ? "; secure" : "");
	}

	function EffacerCookie(nom) {
		date=new Date;
		date.setFullYear(date.getFullYear()-1);
		this.SaveCookie(date);
	}

A utiliser comme ça :
var cookie = new Cookie("nomDuCookie"); //Création du cookie, s'il n'existe pas, valeur vide, s'il existe, il recupere la valeur du cookier
cookie.SetValue("valeur"); //Met la valeur "valeur" dans le cookie et enregistre
On peut aussi utiliser la fonction cookie.saveCookie(plusieurs paramètre) notament pour changer le temps d'existence, le chemin ?, le domaine ?, la sécurité ?. J'ai jamais eu a changé ces paramètres sauf le temps d'existence. Donc a utiliser pour les plus avancés, sinon utiliser simplement cookie.setValue("valeur")
(Est ce vraiment plus simple qu'avec des fonctions ? Moi je prefere en tout cas)

J'ai aussi en reserve une palette de couleur assez complète que j'ai dévellopé qui peut servir à certains : ici
24 décembre 2008 à 12:10:01

Une fonction pour parser une chaine de caractère en objet DOM.
Donc, plus besoin de passer par le innerHTML :
function parse(object_, string_) {
	var regex = new RegExp("(<\/?[^>]+>)", "g");
	if(!(regex.test(string_))) {
		var str = document.createTextNode(string_);
		object_.appendChild(str);
	}
	else {
		var tableau = string_.split(regex);
		var content = false;
		var balise = false;
		
		for(var i=0; i<tableau.length; i++) {
			if(balise) {
				if(/<\/[^>]+>/.test(tableau[i]) && tableau[i].substring(2,tableau[i].length-1) == balise) {
					var node = document.createElement(balise);
					object_.appendChild(node);
					parse(node, content);
					balise = false;
					content = false;
				}
				else 
					content += tableau[i];
			}
			else if(!(regex.test(tableau[i])) && tableau[i] != "")
					object_.appendChild(document.createTextNode(tableau[i]));
			else if(/<[^>]+>/.test(tableau[i])) {
				content = "";
				balise = tableau[i].substring(1,tableau[i].length-1);
			}
		}
	}
}


Et on l'appelle comme ça : parse(document.body, "<p>Hello <em>World</em>! et </p>plouf <em>Yipii</em>ee!");
Vive le DOM :D !
24 décembre 2008 à 12:18:13

Citation : strucky

Suite à la création de ce nouveau forum, j'ai donc transféré


sinon moi j'ai fait(sisi c'est ou moi qui ai fait! mais je me suis inspiré d'autre... qui en amrchaient pas en simple copier coller :s ) un script permettant de rempalcer tous les selects par des div select-like ... donc entièrement personnalisables...
<html>
<head>
<style type="text/css">
.liste{
	position:absolute;
	text-align:left;
	border:3px solid blue;
	white-space:nowrap;
	font:normal 12px verdana;
	display:none;
	background:#fff;
	z-index:100;
}
 
.liste a{
	border:1px solid blue;
	display:block;
	cursor:default;
	color:#000;
	text-decoration:none;
	background:#fff;
}
 
.liste a:hover{
	color:white;
	background-color:blue;
}
.aenlever
{
display:none;
}
</style>
<script type="text/javascript">
var timer;
var fleche='<img style=width:10px;width:10px;" src="http://photoxbc2.free.fr/xbc/flechebas.gif" alt="&darr;" />';
function montrerliste(obj)
{
	cacherlistes();
	obj.parentNode.getElementsByTagName('div')[0].style.display = (obj.parentNode.getElementsByTagName('div')[0].style.display == 'block') ? 'none' : 'block';
	toutcacher();
}
function validerliste(txt, obj){
	obj.parentNode.parentNode.parentNode.getElementsByTagName('input')[0].value = txt;
	obj.parentNode.style.display = 'none';
	obj.parentNode.parentNode.getElementsByTagName('p')[0].innerHTML = fleche+obj.innerHTML;
}
function cacherlistes()
{
	listes=document.getElementsByClassName('liste');
	for(cacherliste=0;cacherliste<listes.length;cacherliste++)
	{
		listes[cacherliste].style.display='none';
	}	
}
function toutcacher(cacherok)
{
	if(!surliste)
	{
		if(cacherok)
		{
			cacherlistes();
		}
		else
		{
			timer=setTimeout("toutcacher(true)",2500);	
		}
	}
}
function setForm()
{
	selects = document.getElementsByTagName('select');
	for(i=0; i<selects.length; i++)
	{
		obj=selects[i];
		newinput = document.createElement("input");
		obj.parentNode.appendChild(newinput);
		newinput.setAttribute('type','hidden');
		newinput.setAttribute('id',obj.id);
		newinput.setAttribute('name',obj.name);
		
		newdiv = document.createElement("div");
		obj.parentNode.appendChild(newdiv);
		newdiv.setAttribute('class','blockliste');
		
		newp = document.createElement("p");
		newdiv.appendChild(newp);
		newp.setAttribute('onclick','clearTimeout(timer);montrerliste(this)');
		
		newliste=document.createElement("div");
		newdiv.appendChild(newliste);
		newliste.setAttribute('class','liste');
		newliste.setAttribute('onmouseover','surliste=true;');
		newliste.setAttribute('onmouseout','surliste=false;timer=setTimeout("toutcacher(true)",1000);');
		
		options=document.getElementById(obj.id).getElementsByTagName('option');
		for(j=0;j<options.length;j++)
		{
			if(j==0)
			{
				if(obj.title!='')
				{
					newp.innerHTML=fleche+obj.title;
				}
				else
				{
					newp.innerHTML=fleche+options[j].innerHTML;
				}	
			}
			newa = document.createElement("a");
			newliste.appendChild(newa);
			newa.setAttribute('href','javascript:void(0)');
			newa.setAttribute('onclick',"validerliste('"+options[j].value+"', this)");
			newa.setAttribute('onmouseover','surliste=true;');
			newa.innerHTML=options[j].innerHTML+'<br>';
		}
	obj.removeAttribute('name');
	obj.removeAttribute('id');
	obj.setAttribute('class','aenlever');
	obj.innerHTML='';
	}
	aenlever=document.getElementsByClassName('aenlever');
	nbaenlever=aenlever.length;
	for(k=0;k<nbaenlever;k++)
	{
		truk=aenlever[0].parentNode;
		disparu = truk.removeChild(aenlever[0]);
	}
}
var surliste=false;
window.onload = function() {
  setForm();
}
</script>
</head>
<body>
<span id="test">AVANT</span>:<br>
	<select id="something" name="something" title="1">
		<option value="1">This is option 1</option>
		<option value="2">This is option 2</option>
		<option value="3">This is option 3</option>
		<option value="4">This is option 4</option>
		<option value="5">This is option 5</option>
	</select>
	<select id="somethingelse" name="somethingelse" title="2">
		<option value="1">This is option 1</option>
		<option value="2">This is option 2</option>
		<option value="3">This is option 3</option>
	</select>
		<select id="something" name="something">
		<option value="1">This is option 1</option>
		<option value="2">This is option 2</option>
	</select>
<br>APRES:<br>
</body>
</html>


page de test:http://xavier.montillet.free.fr/test/listes.html(pas a jur car je suis pas chez moi donc pas d'accès au ftp)

PS:j'ai bien dit que j'ai fait la foction qui remplace... la fonction qui fait que le div ressemble a un select c'est pas moi.... moi c'est juste la fonction js qui rempalce tous les selects...

PS n°2:il rest 2 bug:
-ca marche pas souys ie(et je peux rien y faire car je suis sur mac pour l'isntant...)
-quand on click vite sur une liste puis sur une autre, elle se referme presque imédiatement... et je comprend pas pourquoi...
24 décembre 2008 à 13:29:28

Timot, juste un détail, dans ta dernière optimisation du script gérant les styles, tu as fait une faute de frappe à "length", ligne 4. Si tu peux éditer ça... ^^

Félicitations à vous en tous cas, ces scripts sont vraiment bien ! :)
24 décembre 2008 à 19:30:55

Bon, j'ai optimisé le script pour CSS et j'ai crée l'objet CSS :
EDIT: voir dernière version plus bas

Ses différentes méthodes d'appel :
- CSS.GetStyleText(élément) renvoie les styles de l'élément bout à bout
- CSS.Set(élément, propriété, valeur) change la propriété de l'élément et le met à la valeur demandé (gère les cas ou l'élément n'avait aucune propriété) du genre : CSS.Set("body","color","red");
- CSS.Set(élément, propriétés/valeurs) pour modifier plusieurs propriétés de l'éléments du genre : CSS.Set("#menu ul","width:20px;height:10px;font-size:12px;background-color:white");
- CSS.Clear(élément) ou CSS.Delete(élément) : le premier met tout les style de l'élément à zéro, le second le supprime carrément de la feuille de style

Voila donc comment modifier facilement ses feuilles de style avec javascript ;) .
26 décembre 2008 à 17:00:48

Encore une amélioration de l'objet CSS avec rajout du format JSON pour les propriétés, vous pouvez appeler la fonction Set comme ça :
CSS.Set(".window-base .drag-gauche", {
	backgroundImage:"url('"+site+"images/dragndrop/gauche.png')",
	width: "22px",
	height: "22px",
	margin: "0px",
	padding: "0px",
	_float: "left"
});

Vous remarquerez que les noms composés de propriété sont "compactés" : on enlève le tiret et on met une majuscule (comme pour l'objet style en js), et le mot clé float est échappé d'un underscore (car float est un mot clé en js).
Cependant, on peut aussi faire comme ca pour faire sans ces modifs :
CSS.Set(".window-base .drag-gauche", {
	"background-image": "url('"+site+"images/dragndrop/gauche.png')",
	width: "22px",
	height: "22px",
	margin: "0px",
	padding: "0px",
	"float": "left"
});

Voila donc le petit plus, avec le code source qui va avec :
EDIT: voir dernière version plus bas
27 décembre 2008 à 18:26:48

Quand y'en a plus, y'en a encore !
Voila la version définitive (du moins je l'espère :p ) de mon objet CSS qui est maintenant totalement compatible IE.
Et quelques nouvelles fonctionna litées :
- définir des propriétés seulement pour IE : CSS.Set("#ton élément", "IEmarginLeft", "10px"); Qui peut être très utile dans les problèmes avec les flottants (marge négatives nécessaires pour IE par exemple)
- on peut récupérer la vrai valeur d'une propriété. La valeur effective si vous préférez. Si vous avez mis une taille en % par exemple, avec CSS.GetRealValue("id d'un élément", "width") renverra la taille en pixel de l'élément (comme le offsetWidth mais pour toutes les propriétés). Attention, elle prend en paramètre l'idée d'un élément qui doit être existant un directement un élément mais il doit être existant dans la page et pas seulement défini les feuilles de style.

Voila le code :
/*########################################################
#############  Objet pour faciliter la gestion des feuilles de style en js ############
#########################################################*/
var isIE = navigator.userAgent.toLowerCase().indexOf('msie')!=-1;
var CSS = {
	/*############  Récupérer l'élément ##############*/
	Get: function (element_) {
		for(var i = document.styleSheets.length-1; i>=0; i--) {
			var rules = document.styleSheets[i].rules || document.styleSheets[i].cssRules;
			for(var j=0; j<rules.length; j++) {
				if(rules[j].selectorText == element_) { 
					return rules[j];
				}
			}
			return false;
		}
	},
	
	/*############  Récupérer le style d'un élément ##############*/
	GetStyle: function (element_) {
		return CSS.Get(element_).style;
	},
	
	/*########  Récupérer le style d'un élément version text ###########*/
	GetStyleText: function (element_) {
		return CSS.Get(element_).cssText;
	},
	
	/*########  Récupérer la valeur d'une propriété d'un élément ###########*/
	GetValue: function (element_, propriete_) {
		var rules = CSS.GetStyle(element_);
		if(!rules)
			return null
		if(rules.getPropertyValue){
			return rules.getPropertyValue(propriete_);
		}
		else {
			var prop = propriete_.replace(/\-([A-Z]{1})/g, "$1".toUpperCase());
			return rules[prop];
		}
	},
	
	/*########  Récupérer la valeur effective d'une propriété d'un élément ###########*/
	GetRealValue: function (element_, propriete_) {
		var element = (typeof element_ == "string")? document.getElementById(element_) : element_;
		if (element.currentStyle)
			return element.currentStyle[propriete_];
		else if (window.getComputedStyle)
			return document.defaultView.getComputedStyle(element, null).getPropertyValue(propriete_);
	},
	
	/*############  Changer le style d'un élément  ##############*/
	Set: function(element_, propriete_, value_) {
		var rules = CSS.GetStyle(element_);
		if(!rules) {
			CSS.Add(element_);
			rules = CSS.GetStyle(element_);
		}

		if(typeof propriete_ == "object") {
			for(propriete in propriete_) 
				CSS.SetProperty(rules, propriete, propriete_[propriete]);
		}
		else {
			var propriete = propriete_.replace(/^\s+/g,'').replace(/\s+$/g,'') 

			if(typeof value_ == "string") {
				CSS.SetProperty(rules, propriete, value_);
			}
			else {
				var tableau = propriete.split(/[:;]/);
				for(var i=0; 2*i < tableau.length; i++) {
					CSS.SetProperty(rules, rules_tableau[2*i], tableau[2*i+1]);
				}
			}
		}
	},
	
	/*############  Changer la valeur d'une propriété (compatibilité IE/FF)  ##############*/
	SetProperty: function(rules_, propriete_, value_, importance_) {
		var importance = (typeof importance == "string")? importance_ : "";
		var prop = propriete_.replace("_float", "float");
		if(rules_.setProperty && !((/^IE/g).test(prop))){
			prop = prop.replace(/([A-Z]+)/g, "-$1");
			prop = prop.toLowerCase();
			rules_.setProperty(prop, value_, importance);
		}
		else {
			if(((/^IE/g).test(prop))){
				if(!isIE)
					return false;
				else
					prop = prop.replace("IE", "");
			}	
			prop = prop.replace(/\-([A-Z]{1})/g, "$1".toUpperCase());
			rules_[prop] = value_ + importance;
		}
	},
	
	/*##########  Rajoute un élément  ############*/
	Add: function(element_) {
		var styleSheet = document.styleSheets[0];
		var rules = styleSheet.rules || styleSheet.cssRules;
		if(styleSheet.insertRule)
			styleSheet.insertRule(element_+" { }", rules.length);
		else if(styleSheet.addRule)
			styleSheet.addRule(element_, "{ }");
	},
	
	/*##########  Met tout les styles de l'élement à zéro ############*/	
	Clear: function(element_) {
		var text = CSS.GetStyleText(element_);
		text = text.substring(text.indexOf("{")+1, text.lastIndexOf("}"));
		var proprietes = text.split(/[:;]/);
		for(var j=0; 2*j < proprietes.length-1; j++) {
			CSS.Set(element_, proprietes[2*j], "");
		}
	},
	
	/*##########  Supprime l'élement de la feuille de style  ############*/		
	Delete: function(element_) {
		var rule = CSS.Get(element_);
		var parent = rule.parentStyleSheet;
		parent.deleteRule(rule);
	}
}


Remarque : vous pouvez utiliser votre propre variable isIE si vous avez déja une variable de ce type ;) .

Bonne utilisation à tous ;) .
28 décembre 2008 à 12:04:35

Oups, désolé, je ne suivais plus ce sujet.

Bon, je ne sais que trop penser de tous ce que vous avez proposé, cela s'apparente plus à des scripts que des problèmes pouvant-être intégré à une FAQ, à la limite, on pourrait faire une sous-partie dans la FAQ pour les scripts et fonctions utilisateurs ?

Citation : xavierm02

Citation : strucky

Suite à la création de ce nouveau forum, j'ai donc transféré


sinon moi j'ai fait(sisi c'est ou moi qui ai fait! mais je me suis inspiré d'autre... qui en amrchaient pas en simple copier coller :s ) un script permettant de rempalcer tous les selects par des div select-like ... donc entièrement personnalisables...



Je dois être con, mais j'ai pas compris pourquoi tu me cites en rayant le donc...
28 décembre 2008 à 12:44:09

C'est vrai que le donc est pas utile dans cette phrase... mais bon, au point de le barrer... ^^

Oui, ça pourrait être bien de faire une sous-partie comme ça.

Moi, je suis en train de penser à un truc, je ne me souviens pas l'avoir vu dans la FAQ... C'est quand les gens essaient d'appeler des éléments dans leurs scripts (avec getElementById par exemple), alors que l'élément en question n'est pas encore chargé...
(Par exemple en plaçant le code dans le body, mais avant l'élément en question.)
28 décembre 2008 à 14:05:05

Ouaip, ce genre de truc arrive fréquemment (j'y ai eu droit aussi :-° ), et cela peut paraître surprenant quand on passe d'un langage serveur au js.

Mais je te laisse le loisir de le faire :p
28 décembre 2008 à 14:31:26

Je fais ça dans ce topic, là, comme ça, spontanément ? Ok...

Pourquoi je n'arrive pas à accéder à un élément de la page, avec getElementById() ou autres méthodes similaires ?


Réponse :

Il est probable que vous soyez en train d'appeler un élément qui n'a pas encore été chargé... Alors forcément, ça coince...
Pour s'assurer que l'élément est bien chargé lorsque le javascript est exécuté, il y a deux solutions.

1) Soit mettre tout sous forme de fonctions dans la partie "head" de la page.
Exemple :
<head>
<script type="text/javascript">
function appel() {
div = document.getElementById("conteneur");
div.style.textAlign = "center";
}
</script>
</head>

Ici, la fonction sera appelée soit avec <body onload="appel();"> , soit par une action du visiteur. Donc le chargement sera terminé dans les deux cas, et l'élément accessible. :)



2) Soit vous placez le code dans la partie "body", et là méfiez-vous ! Il faut que le code soit situé après l'élément appelé.
Exemple :
<body>
<div id="conteneur">
<!-- Contenu du div -->
</div>
<script type="text/javascript">
div = document.getElementById("conteneur");
div.style.textAlign = "center";
</script>
</body>

28 décembre 2008 à 17:28:37

En effet, ce que j'ai proposé plus haut semble s'apparenter plus à des utilitaires qu'a autre chose.
Cependant, j'ai quand même quelques questions récurrentes à apporter à la FAQ.
Comment faire en javascript pour avoir des noms de variables dynamiques

Dans certains cas, on est obligé d'utiliser des noms de variable dynamiques (surtout pour optimiser le code), voila comment on procède en javascript :
- lorsque c'est une variable "normale", on peut l'atteindre ainsi : window[variable]
Ainsi, on peut faire :
for(var i = 0; i<5; i++){
   window["test_nbr_"+i] = (4*i + 2)%7;
}

- lorsque c'est un objet (même pour this), on peut l'atteindre ainsi : objet[variable]

Comment faire pour redéfinir des fonctions natives de javascript ?

Il arrive qu'on veuille redéfinir certaines fonctions natives de javascript dans certains cas.
Par exemple, imaginez quelqu'un qui à repris le fameux script de lightbox, l'a modifié de sorte qu'on puisse afficher du texte facilement.
Il souhaiterait pouvoir redéfinir la fonction alert afin qu'elle affiche le message dans la lightbox plutôt que la boite habituelle du navigateur.
Voila à quoi ressemblerait son code:
var CS_alert = alert; //On sauvegarde l'ancien code d'alert
alert = function(str_){
  LightBox(str_); //Fonction d'affichage dans une lightbox
}

Remarque : la sauvegarde du code d'alert (var CS_alert = alert) permet de conserver son code, par exemple si on veut juste rajouter certaines instructions à la fonction alert mais qu'on veut quand même pouvoir appeler la fontion initale dans certains cas.
Par exemple :
var CS_alert = alert; //On sauvegarde l'ancien code d'alert
alert = function(str_){
  if(condition) {
     CS_alert(str_);
  }
}

Ainsi, par exemple, certains redéfinissent la fonction alert pour qu'elle ne puisse afficher que 30 alert à la suite, pour éviter les plantages du navigateur.
Voila donc, ça peut être utile à certains ;) .
29 décembre 2008 à 22:17:26

Comment rajouter des événements dynamiquement, c'est à dire sans le mettre dans les balises ?

Il y a plusieurs manières de le faire, la plus propre reste d'utilise l'addEventListener.
Cependant IE nécessite lui attachEvent pour faire la même chose.
Donc :
if( obj.attachEvent){
        obj.attachEvent('on' + event,fct);
}
else {
        obj.addEventListener(event,fct,true);
}

Cependant, dans les fonctions ou le mot clé this est utilisé, par exemple onmouseover="this.src='nouvelle source'", IE ne peut pas le gérer avec ce code, on est obligé d'attacher l'événement avec obj.evenement = ...
Voila donc une fonction qui permet d'attacher une fonction à un événement :
function addEvent(obj_, event_, fct_) {
	if(obj_.addEventListener) {
		obj_.addEventListener(event_, fct_, true);	
	}
	else if(obj_.attachEvent) {
		if(/this\./g.test(fct_.valueOf())){
			obj_['on' + event_] = fct_;
		}
		else {
			obj_.attachEvent('on' + event_, fct_);
		}
	}
}


Exemples :
addEvent(window, "load", Ini);
addEvent(document.getElementById("test"), "click", Test);

Pour pouvoir appeler les fonctions avec des arguments, il faut passer par une fonction anonyme qui se chargera d'appeler notre fonction avec ses arguments

Exemples :
addEvent(window, "load", function(event) { Ini(param, param2); });
A noter que le paramètre event est automatiquement envoyé à la fonction qu'on lui donne.

A noter aussi que l'on n'est pas obligé de passer par une fonction nommé et que l'on peut mettre toute nos instructions dans la fonction anonyme :
addEvent(window, "load", function(event) {
   document.getElementById("test").style.color = "blue";
   alert("Vive les lapins !!");
   onLoaded = true;
});
29 décembre 2008 à 22:37:32

réponse pour stucky

Citation : strucky


Citation : xavierm02

Citation : strucky

Suite à la création de ce nouveau forum, j'ai donc transféré


sinon moi j'ai fait(sisi c'est ou moi qui ai fait! mais je me suis inspiré d'autre... qui en amrchaient pas en simple copier coller :s ) un script permettant de rempalcer tous les selects par des div select-like ... donc entièrement personnalisables...


Je dois être con, mais j'ai pas compris pourquoi tu me cites en rayant le donc...



c'est une faute de syntaxe...

tu pourrais aussi bien dire:
"Comme il fait beau, donc je sors!"... 2 mots qui ne doivent pas être utilisés ensemble dans cette phrase...
la t'as juste mis "suite à " à la palce de "comme"
bref tu écris comme tu veux :p mais moi ça m'a choqué... en même temps vu mon orthographe je devrais pas trop parler :-° mais j'ais pas pu me retenir :p


PS:non ce message ne va pas juste servir a répondre à ca, je vais l'éditer dnas la soirée pour mettre la nouvelle verssion du script (pitetre qu'elle marchera avec ie !)
EDIT:pas de nouvelle version ce soir...
29 décembre 2008 à 23:31:10

Citation : Timot


addEvent(window, "load, funcion(event) {
   document.getElementById("test").style.color = "blue";
   alert("Vive les lapins !!)";
   onLoaded = true;
});


T'as buggué sur ton clavier là je crois. ^^ 3 petites fautes de frappe qui se baladaient.

addEvent(window, "load", function(event) {
   document.getElementById("test").style.color = "blue";
   alert("Vive les lapins !!");
   onLoaded = true;
});

29 décembre 2008 à 23:43:26

Vi, mon ordi lague un peu et n'arrive pas à me suivre. Rajoute à ca la fatigue, et j'écris n'importe quoi !
Bon, j'édit alors ;) .
29 décembre 2008 à 23:57:45

Citation : Timot


- lorsque c'est une variable "normale", on peut l'atteindre ainsi : window[variable]
Ainsi, on peut faire :

for(var i = 0; i<5; i++)
   var window["test_nbr_"+i] = (4*i + 2)%7;


J'ai voulu testé ce bout de code, vu que je connaissais pas les variables dynamiques... Mais Firebug n'est pas très content et ça marche pas.
Par contre quand j'enlève le "var" devant le "window[]", ça marche... Quelqu'un a une explication rationnelle ?
30 décembre 2008 à 1:14:14

Un petit truc tout bête mais sur lequel certains débutants se plantent parfois :

Comment accéder à l'attribut class d'une balise ?


En Javascript, le mot class est déjà réservé, ce qui fait que l'on ne peut pas accéder à la classe d'une balise par ce moyen :

alert(document.getElementById('test').class);


Pour y avoir accès il faut utiliser le mot className :

alert(document.getElementById('test').className);


Golmote -> J'ai constaté que le Javascript a tendance à gueuler quand on ne met pas les accolades d'une fonction/boucle/etc même pour une ligne, essaye avec et dis-moi après :) .
Anonyme
30 décembre 2008 à 1:25:37

window c'est l'objet global, l'utiliser explicitement c'est un signe d'echec. Avoir autant de variable globales c'est uniquement chercher des problèmes.

Pour la question du "var" c'est trivial, tu ne fais pas
var tonObjet.variable = "truc";
// mais tout simplement 
tonObjet.variable = "truc";

on rajoute un membre à l'objet (quelque soit l'objet. "window" est un objet), on ne rajoute pas de variable au contexte parent, donc pas besoin de "var".
C'est une question de portée et de bon sens. Si tu avais un peu d'idée sur comment fonctionne les objets en javascript ça devrait être évident.

En passant le code de Timot fait peur à voir, mélanger les if avec parenthèses et sans parenthèses c'est du grand n'importe quoi et ça n'a rien a faire dans une FAQ déstinée aux débutants. Ça embrouille et ce sont des mauvaises pratiques. Autant les habituer directement aux bonnes.

Pour la question de la place de <script> c'est un non débat. Il doit être placé juste avant </body> et pas dans le <head> pour ne pas géner le chargement du html et du CSS. En plus ça permet d'éviter d'utiliser window.onload vu que le html est déja chargé quand le js l'est.

Ça part d'un bon sentiment, mais pour le moment ça part surtout n'importe où.
30 décembre 2008 à 9:42:09

Citation : Golmote

Citation : Timot


- lorsque c'est une variable "normale", on peut l'atteindre ainsi : window[variable]
Ainsi, on peut faire :

for(var i = 0; i<5; i++)
   var window["test_nbr_"+i] = (4*i + 2)%7;



J'ai voulu testé ce bout de code, vu que je connaissais pas les variables dynamiques... Mais Firebug n'est pas très content et ça marche pas.
Par contre quand j'enlève le "var" devant le "window[]", ça marche... Quelqu'un a une explication rationnelle ?


narmal : quand tu met var dans une focntion, ca définit la variable comme locale... et elle est suprimée a la fin de la focntion... or une fonction qui est dans window est une focntion globale... bref la t'a une focntion globale et locale a la fois.. donc problème...

PS:youpie nod_ n'a pas critiqué mon script :p
Anonyme
30 décembre 2008 à 10:14:53

Pas forcément. Les closures permettent de garder les variables d'une fonction même (et surtout) après la fin de l'execution de la fonction. Même si ça a l'air logique, c'est pas le conflit variable global/locale le problème. Mais bien la syntaxe de définition de la variable qui est mauvaise.

J'avais pas fait attention au scripts tout en haut, comparativement il a "commis" plus que toi sur ce post, et même si tu mériterai la décapitation pour quelques points, c'est plutôt des erreurs de bonnes foi à mon avis.
30 décembre 2008 à 11:41:27

Citation : nod_

Si tu avais un peu d'idée sur comment fonctionne les objets en javascript ça devrait être évident.


J'ai jamais prétendu en avoir... et il n'est jamais trop tard pour l'acquérir. Par contre, ce serait cool que les savants du JS (ceux qui savent) se mettent d'accord sur les règles de placement par exemple, ou de parenthèses...
Ca éviterait ces éternels débats.

Citation

PS:youpie nod_ n'a pas critiqué mon script


Non, mais il a critiqué ton post ! :p
30 décembre 2008 à 13:03:24

Citation : nod_

même si tu mériterai la décapitation pour quelques points


bah je veux bien savoir les points :p
histoire de pouvoir corriger les ereures... et comme ca ca marchera peut etre sous ie...
PS:'ai cru comprendre que tu n'aimais pas innerHTML ... mais je voit pas quoi utiliser d'autre...
Anonyme
30 décembre 2008 à 13:33:50

boarf j'ai rien contre innerHTML c'est super pratique.

setTimeout("toutcacher(true)",2500); mais setTimeout(toutcacher,2500, true);

tu mélange le dom et l'ajout sauvage de html. Fait un choix sur la méthode. Utiliser setAttribute("onclick","tonjavascript") c'est peut être pratique, mais c'est sub-optimal au mieux.
encore une fois, fait un choix, rajoute le html comme un bourrin '<tag onclick="machin" class="bidule">' ou fait ça proprement avec tonDOMElement.onclick = function () …

Et pour la beauté de la chose mettre tout ça dans un seul objet pour pas polluer l'espace global de variables et fonctions en tous genres.

( edit ) y'a aussi moyen d'optimiser les boucles, histoire de pas aller chercher plusieurs fois les mêmes élements


c'est sur la bonne voie :)

FOIRE AUX QUESTIONS - ANNEXE

× 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