Bonjour,
Je trouve que ça ressemble beaucoup à la technique proposée récemment par Koala64 pour limiter les variables globales à l'aide d'objets littéraux, et je comprends de ton tuto que tu as le même but que lui ou presque.

Ce que j'ai compris de sa version à lui :

var obj1 ={
'propriete1' : 1,
'propriete2' : "Salut tout le monde !",
'methode1' : function () { alert(this.propriete1); },
'methode2' : function () { alert(this.propriete2); }
}


La tienne en diffère que peu :

var obj1 =function () {
function methode1 () { alert(this.propriete1); },
function methode2 () { alert(this.propriete2); }

return {
'propriete1' : 1,
'propriete2' : "Salut tout le monde !",
'methode1' : methode1,
'methode2' : methode2
};}


Maintenant si je compare, pour appeler une des méthodes à l'aide du code à la Koala64, il suffit de :
obj1.methode1();

Pour le tien, ce n'est pas tout à fait vrai.
En effet, dans ton cas, obj1 est une fonction et elle ne contient par conséquent pas les propriétés et méthodes auxquelles tu t'attends. En fait, ces propriétés appartiennent à l'objet retourné par ta fonction. Ce qui change un peu la syntaxe :
obj1().methode1();

En outre, tu as un autre inconvénient : ton objet est recréé à chaque fois que tu en as besoin, alors que ce n'est pas forcément nécessaire.
Le seul avantage que je vois est de pouvoir créer des méthodes dites publiques et privées comme on en trouve dans la plupart des langages objet.
Si tu veux vraiment faire ça, pourquoi ne pas créer une classe ? ce n'est pas si différent... pour reprendre l'exemple ça serait un truc comme :

function classeObj1 () {
this.propriete1 = 1;
this.propriete2 = "Salut tout le monde !";
this.methode1 = function () { alert(this.propriete1); }
this.methode2 = fonction () { alert(this.propriete2); }
}

C'est bien, mais dans le cas d'une bibliothèque de fonctions encapsulés, tu n'auras probablement pas besoin d'instancier plusieurs objets. Donc, une classe, à mon avis, est inutile pour n'en utiliser qu'un seul objet.

IL se peut que je n'aie pas bien compris le but de ton tuto ... mais pour l'instant tel que je le comprends, je préfère la version de Koala64.
Bonjour,

Tout d'abord, l'idée de départ de mon tutoriel est de se concentrer sur le problème des espaces de nommage, ce qui est de mon point de vue un sujet important que je n'ai donc pas été surpris de trouver dans un tutoriel sur les bonnes pratiques Javascript (c'est-à-dire celui de Koala64).

Comme tu le dis, j'ai en effet le même but que lui, mais j'espère que dans mon cas, en me concentrant sur ce sujet, je l'explique plus précisément. De plus, le texte que je soumets ici n'est pas définitif et il y a largement matière à l'approfondir.

Pour répondre plus précisément à tes questions, tu n'as en effet pas totalement compris le code de mon tutoriel. Comme je l'ai indiqué explicitement, pour accéder à l'interface publique de l'espace de nommage, il suffit (comme pour la version de Koala64) de :
obj1.methode1();

De plus, mon objet n'est créé qu'une seule fois et obj1 n'est pas une fonction mais le littéral objet que l'on retourne dans la fonction.

Je pense que ce qui t'a induit en erreur est que tu n'as pas relevé qu'il y avait deux parenthèses () après la déclaration de la fonction. La fonction est déclarée puis immédiatement appelée.

Comme je l'indique dans mon tutoriel, l'intérêt de cette méthode à mon avis est qu'elle s'intègre facilement à du code existant. Supposons que tu aies le code suivant :
function methode1() {
  alert(propriete1);
}

function methode2() {
  alert(propriete2);
}

var propriete1 = 1;
var propriete2 = "Salut tout le monde";

La version de Koala64 donnera :
var obj1 ={
  "propriete1": 1,
  "propriete2": "Salut tout le monde !",
  "methode1" : function () { alert(this.propriete1); },
  "methode2" : function () { alert(this.propriete2); }
};

Quant à celle que je propose :
var obj1 = function() {
  function methode1() {
    alert(propriete1);
  }

  function methode2() {
    alert(propriete2);
  }

  var propriete1 = 1;
  var propriete2 = "Salut tout le monde";

  return {
    "propriete1": propriete1,
    "propriete2": propriete2,
    "methode1": methode1,
    "methode2": methode2
  };
}();

Je pense qu'il n'est pas exagéré de dire que la transition est plus facile dans le second cas, surtout si le volume de code est important et que l'interface publique est réduite (contrairement à cet exemple).

Et puis, en plus de gérer l'encapsulation (ce qui est pour moi loin d'être un aspect négligeable), ma solution permet d'exécuter du code statique au sein de l'espace de nommage (comme dans mon exemple d'espace de nommage anonyme).

Pour conclure, je répèterai le point sur lequel j'insiste dans mon texte : ma méthode n'est ni l'unique ni la meilleure.
Modifié par Eldebaran (25 Oct 2006 - 00:19)
Modérateur
Salut,

C'est un peu deux styles de programmation qui s'affrontent... Smiley cligne

Personnellement, je trouve ton tuto bien fait, clair et concis et cette notion est bien expliquée. Néanmoins, pour moi, aucune des deux méthodes n'a l'avantage...

a écrit :
ma solution permet d'exécuter du code statique au sein de l'espace de nommage (comme dans mon exemple d'espace de nommage anonyme).

Dans les deux cas, nous pouvons faire la même chose. Je peux aussi exécuter un code au sein même de chaque méthode et ce, sans interface publique.

var oO =
{
	_Method : function()
	{
		var oO =
		{
			_Alert : function()
			{
				alert('coucou!');
			}
		};
		oO._Alert();
	}
};
oO._Method();

Après, c'est à chacun de choisir ce qu'il préfère effectivement... Smiley smile
Ah, non, effectivement, je n'avais pas relevé que tu déclarais la fonction et que tu l'appelais immédiatement après.

Mais dans l'exemple que tu me donnes, je ne suis pas certain que :

obj1 = function () { /* ... */ }();
obj1.propriete1 = 1234.5678;
obj1.methode1();

M'affiche bien 1234.5678... j'aurais tendance à dire que le 1 est conservé à cause de l'absence du this dans ta version. Ca peut être rapidement un piège... ne pas oublier le this donc.
koala64 a écrit :
Personnellement, je trouve ton tuto bien fait, clair et concis et cette notion est bien expliquée. Néanmoins, pour moi, aucune des deux méthodes n'a l'avantage...
Merci !

Je suis parfaitement d'accord avec toi. Le choix d'une de ces deux méthodes (et des innombrables autres que l'on peut imaginer) dépend du besoin de l'utilisateur, de son envie, et peut-être même de ce qu'il a mangé au repas précédent. Smiley cligne
koala64 a écrit :
Dans les deux cas, nous pouvons faire la même chose. Je peux aussi exécuter un code au sein même de chaque méthode et ce, sans interface publique.

var oO =
{
	_Method : function()
	{
		var oO =
		{
			_Alert : function()
			{
				alert('coucou!');
			}
		};
		oO._Alert();
	}
};
oO._Method();
Certes. Par contre je dois t'avouer que je ne comprends pas trop l'utilité du second objet oO dans _Method.
QuentinC a écrit :
Mais dans l'exemple que tu me donnes, je ne suis pas certain que :

obj1 = function () { /* ... */ }();
obj1.propriete1 = 1234.5678;
obj1.methode1();
M'affiche bien 1234.5678... j'aurais tendance à dire que le 1 est conservé à cause de l'absence du this dans ta version. Ca peut être rapidement un piège... ne pas oublier le this donc.
En effet, tu as raison.

En fait, je dois avouer que je n'avais pas vraiment envisagé dans mon tutoriel la possibilité de mettre des propriétés dans l'interface publique (voilà encore une chose à modifier).

Pour ma part, je préfère en général éviter l'utilisation de this dans un espace de nommage, pour esquiver ce genre d'ambiguïtés :
var obj1 = function() {
  function methode1() {
    alert(this.propriete1);
  }

  return {
    "methode1": methode1,
    "propriete1": 1
  };
}();

window.onload = obj1.methode1;
En effet, dans ce cas-là, on obtiendra on joli "undefined".

Quand j'ai besoin de propriétés publiques (en général pour des besoins de paramétrage d'un module), j'utilise la syntaxe suivante :
var obj1 = function() {
  function methode1() {
    alert(ns.propriete1);
    alert(priv1);
  }

  var priv1 = 1234;

  var ns = {
    "methode1": methode1,
    "propriete1": 4321
  };
  return ns;
}();
Pour accéder à une variable publique de l'espace de nommage, on utilise alors ns.nomPropriete (ns.propriete1 dans l'exemple), tandis que l'accès aux variables privées se fait sans résolution de portée (priv1 dans l'exemple).

Merci pour vos retours en tout cas, ça me donne déjà du boulot pour modifier mon tuto. Je suis bien évidemment toujours ouvert à d'autres remarques.
Modifié par Eldebaran (25 Oct 2006 - 11:05)
a écrit :

En fait, je dois avouer que je n'avais pas vraiment envisagé dans mon tutoriel la possibilité de mettre des propriétés dans l'interface publique (voilà
encore une chose à modifier).

Selon les besoins que tu as, tu n'es effectivement pas obligé de mettre des propriétés publiques. Tu peux très bien, comme on le fait dans la plupart des langages objet, privatiser complètement les propriétés et ne laisser l'accès qu'à des couples de méthodes get/set. L'accès public est une façon de simplifier, parce qu'en général, on n'a pas besoin d'une telle artillerie pour du js, les scripts ne sont en général pas si longs que ça (quelqu'un a-t-il déjà vu un javascript de plus de 5000-10000 lignes ?)
L'avantage d'encapsuler totalement, c'est que tu réduis les risques d'erreur puisque tu peux contrôler les valeurs attribuées.

a écrit :

window.onload = obj1.methode1;
En effet, dans ce cas-là, on obtiendra on joli "undefined".

Normal puisque le this représentera dans ce cas l'objet window. En effectuant window.onload = unefonction, tu crées en quelque sorte une nouvelle méthode que tu attribues à l'objet window (en fait créer n'est pas tout à fait le terme approprié : tu ne fais normalement pas une copie de la fonction en mémoire, tu réutilises un pointeur).
Pour ce cas précis, il aurait fallu écrire :
window.onload = function () { obj1.methode1(); }
QuentinC a écrit :
Pour ce cas précis, il aurait fallu écrire :
window.onload = function () { obj1.methode1(); }
C'est en effet une solution, mais il faut bien avoir conscience qu'en faisant cela tu crées une closure (fermeture ?), ce que l'on préfère en général éviter si l'on n'en a pas réellement besoin.

Et puis je pense qu'il vaut mieux que ce soit la syntaxe de l'espace de nommage qui gère ce problème plutôt que l'utilisateur.
Modifié par Eldebaran (25 Oct 2006 - 21:10)
Une closure ? C'est quoi ça ? jamais entendu parler...

Sinon, tu pourrais parfaitement remplacer le this par obj1, en fait. Ce qui lève le problème.
Modifié par QuentinC (26 Oct 2006 - 06:46)
QuentinC a écrit :
Une closure ? C'est quoi ça ? jamais entendu parler...
Je te conseille de lire ça (par contre, c'est en anglais et assez long)
http://www.jibbering.com/faq/faq_notes/closures.html

QuentinC a écrit :
Sinon, tu pourrais parfaitement remplacer le this par obj1, en fait. Ce qui lève le problème.
Certes.

A moins que l'utilisateur n'écrase obj1 (oui je sais, c'est un peu parano).

Ca pose aussi problème si tu décides de renommer ton espace de nommage.
Modifié par Eldebaran (26 Oct 2006 - 09:45)
a écrit :

Ca pose aussi problème si tu décides de renommer ton espace de nommage.

Bah, le rechercher-remplacer, ça existe, non ?

ET c'est vraiment parano de penser que l'utilisateur va écraser obj1. En choisissant bien le nom, à mon avis, il n'y a pas de risques.
QuentinC a écrit :
Bah, le rechercher-remplacer, ça existe, non ?

ET c'est vraiment parano de penser que l'utilisateur va écraser obj1. En choisissant bien le nom, à mon avis, il n'y a pas de risques.
Le surplus de code à ajouter est vraiment insignifiant, et en plus tu peux choisir un nom court comme "ns", ce qui t'évitera d'avoir à répéter pas mal de fois ton nom d'espace de nommage dans ton code (surtout si, comme tu le dis, tu l'as bien choisi et qu'il fait donc plus de trois lettres).

S'il y a quelque chose en quoi je crois depuis que je fais de l'informatique, c'est qu'il est salutaire d'anticiper les erreurs si ce n'est pas trop couteux. Dans ce cas précis, non seulement c'est très peu couteux, mais en plus une faute de frappe dans le nom de l'espace de nommage ou l'oubli du changement de ce nom quelque part arrivera tôt ou tard à mon avis.
Modérateur
Salut, Smiley biggrin

Alors là, tu vois, tu viens de me donner LA solution... Smiley ravi

mmh... ton tuto... tu as une chose extrêmement intéressante à portée de main depuis le début mais non, tu ne l'as que touché du doigt ! Smiley lol

Prenons ta fonction anonyme :
(function() {
   function init()
   {
      document.body.className = jsClassName;
   }
   var jsClassName = "jsActif";
   window.onload = init;
})();

Quel est son principal soucis (qui est d'ailleurs le même que pour mes objets) ?
C'est que si je récupère un script comme suit :

function init()
{
   alert('coucou');
}
window.onload = init;

ben, t'as l'un des deux qui plante... car tu n'élimines pas totalement le risque d'interaction avec d'autres bibliothèques... Pourquoi ?
Simplement parce que tu te sers de onload... Smiley cligne
Pourtant, le véritable intérêt de ta fonction est justement qu'elle n'a pas d'interface publique DONC si tu es capable de la rendre non intrusive, tu l'élimines bien ce risque... Smiley smile

Voici un exemple concret de comment coder le micmac :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
		<title>Exemple</title>
		<script type="text/javascript">//<![CDATA[

		// Biblio 1
		( function() {
			var fConnect = function(oElem, sEvType, fn, bCapture)
			{
				oElem.addEventListener ?
					oElem.addEventListener(sEvType, fn, bCapture):
					oElem.attachEvent ?
						oElem.attachEvent('on' + sEvType, fn):
						oElem['on' + sEvType] = fn;
			};
			var fLink = function()
			{
				var oBouton = document.createElement('a');
				oBouton.setAttribute('href','#clic');
				var oTxt = document.createTextNode('clique');
				oBouton.appendChild(oTxt);
				fConnect(oBouton, 'click', fAlert, false);
				var oBody = document.getElementsByTagName('body')[0];
				oBody.appendChild(oBouton);

				var oA = document.getElementById('test');
				fConnect(oA, 'click', function(e)
				{
					alert('çà va ?');
					return fCancelClick(e);
				}, false);
			};
			var fCancelClick = function(e)
			{
				if(e && e.stopPropagation && e.preventDefault)
				{
					e.stopPropagation();
					e.preventDefault();
					return false; // Pour Safari
				}
				else if(window.event && window.event.cancelBubble && window.event.returnValue)
				{
					window.event.cancelBubble = true;
					window.event.returnValue = false;
					return false;
				}
				else return false;
			};
			var fAlert = function(e)
			{
				alert('coucou');
				return fCancelClick(e);
			};
			fConnect(window, 'load', fLink, false);
		} )();

		//Biblio 2
		function fLink()
		{
			var oA = document.getElementById('test');
			oA.onclick = function()
			{
				alert('bien ?');
				return false;
			};
			alert('salut');
		}
		window.onload = fLink;
		//]]></script>
	</head>	
	<body>
		<p>Test des fonctions associées au clic :</p>
		<a href="#" id="test">test</a>
		<p>Insertion d'un lien qui fait coucou avec la fonction anonyme :</p>
	</body>
</html>
Ici, ta biblio1 ne craint plus rien et ne dérange pas le code ( tout pourri récupéré d'on ne sait où Smiley langue ) qu'est la biblio2... Le risque d'interaction avec d'autres scripts est bien réduit à néant. Smiley smile
Dès lors, tes réelles contraintes sont de coder proprement quelquesoit les événements et de faire attention au sein de tes propres fonctions... (voir dans la première bibliothèque ci-dessus comment sont déclenchées les actions)

Elle est là la conclusion à laquelle tu dois arriver... Smiley cligne

Pour ce qui est du reste, je t'avouerais que la première version me semblait plus accessible aux débutants. En ce moment, certaines des phrases que tu emploies me paraissent un peu âpres à comprendre... Il faut que tu minimises leur longueur en évitant les rallonges... Développe en deux phrases si besoin est mais c'est important d'argumenter de manière concise.

Enfin, pour mieux cerner le pourquoi du comment, je verrais bien un commencement avec une explication complète du fonctionnement des parenthèses... (quand est-ce qu'on doit les employer, quand est-ce qu'on ne le doit pas, ce qu'elles permettent de faire, etc...) car c'est un point obscur pour beaucoup, en particulier lorsqu'on joue avec les événements.

En tout cas, si je ne me suis pas trompé, j'adopte direct cette technique et je déclare ce post sous licence creative ! Smiley biggol

PS : A ceux qui ont croisé ce sujet ainsi que celui ici présent, vous n'avez pas fini d'en bouffer de la gestion d'événements. Smiley lol

Bonne nuit ! Smiley ravi
Modifié par koala64 (14 Nov 2006 - 00:25)
Bonsoir,

Merci pour ta réponse. Smiley smile

Pour ce qui est de mon exemple de fonction anonyme, comme je l'ai précisé, il est simpliste. Pour ma part, j'utilise quelque chose de similaire à ce que tu as proposé, qui permet en effet d'isoler totalement le code et donc de ne pas craindre le code "tout pourri récupéré d'on ne sait où". Smiley cligne

Ca peut être intéressant d'évoquer cette solution, même si ce n'est pas le sujet principal du tutoriel. Ceci dit, c'est vrai que ça permet d'illustrer l'intérêt de l'espace de nommage anonyme.

Tu dis que la nouvelle version est moins accessible aux débutants. Je suppose que ça doit être au niveau du contenu que j'ai ajouté (oui je sais, je suis logique Smiley cligne ). Est-ce que tu as quelques exemples à me donner s'il te plait ? Je manque malheureusement de pédagogie...

Quant aux parenthèses, tu parles de la différence entre function() {} et function() {}() ?

Merci en tout cas pour tous ces éléments !
Modifié par Eldebaran (14 Nov 2006 - 10:45)
Pour ce qui est du risque de collision avec d'autres bibliothèques, il n'est malheureusement jamais totalement nul avec Javascript, preuve en est l'exemple de l'une des versions de Prototype qui modifiait le prototype d'Object et faisait ainsi planter le code basé sur les boucles du type :
for (var i in obj) {}
Je te rejoins cependant sur le fait que, moins le risque d'interaction est grand, moins on court de risques.
Modifié par Eldebaran (14 Nov 2006 - 10:50)
Modérateur
Hello,

a écrit :
Ca peut en effet être intéressant d'évoquer cette solution, même si ce n'est pas le sujet principal du tutoriel. Ceci dit, c'est vrai que ça permet d'illustrer l'intérêt de l'espace de nommage anonyme.
Le titre du tuto est bien "les espaces de nommage en javascript" mais l'ensemble de ton article est fondé sur les interactions que peuvent avoir deux bibliothèques. Lorsque tu dis :
a écrit :
Ce n’est cependant pas satisfaisant puisque, contrairement à la première solution, la bibliothèque devient inaccessible de l’extérieur : on a créé un espace de nommage anonyme.
En quoi ce n'est pas satisfaisant ? C'est justement le but recherché. Le plus gros risque provient surtout du code que tu ne maîtrises pas, c'est à dire, de celui des autres... Tu peux, pour toi, définir une interface accessible mais uniquement au sein de ta fonction anonyme car tu n'as aucun intérêt à rendre ton script accessible de l'extérieur.

a écrit :
Cela peut s’avérer utile dans le cas d’une bibliothèque anonyme (dans le sens où aucun code extérieur n’en dépend) comme la suivante (elle aussi simpliste)
Cette phrase n'est pas juste. Comme dit précédemment, il existe encore des interactions à cause des gestionnaires d'événement onbidule... d'où l'intérêt d'apporter des précisions à ce sujet. Si tu as montré comment te protéger au mieux des autres, tu ne précises pas comment ne pas empiéter sur leur terrain alors que c'est tout aussi important... Si si, je t'assure, faut vivre en symbiose avec ses petits copains... Smiley cligne
Certes, ça va étendre un peu plus le champ d'action du tuto mais vu que le but principal est bien cette notion d'interaction, autant s'attacher à cette dernière plutôt qu'à décrire la technique hors contexte. Ca n'en sera que plus convaincant.

a écrit :
Tu dis que la nouvelle version est moins accessible aux débutants. Je suppose que ça doit être au niveau du contenu que j'ai ajouté (oui je sais, je suis logique Smiley cligne ). Est-ce que tu as quelques exemples à me donner s'il te plait, je manque de pédagogie ?
euh ben par exemple, la phrase suivante fait un peu mal à la tête... Smiley langue
a écrit :
Ce n’est d’ailleurs pas étonnant si l’on sait que function f() {} est équivalent à var f = function() {}; (placé au début de la portée ou du fichier), et donc que la définition d’une fonction n’est qu’un raccourci pour la définition d’une variable faisant référence à cette fonction.
On a vite les bigoudis qui poussent. Smiley ravi Je pense que tu peux simplifier.

a écrit :
Quant aux parenthèses, tu parles de la différence entre function() {} et function() {}() ?
Oui par exemple mais tu peux aussi expliquer :
- pourquoi on doit écrire ( function() { ... } )(); et pas ( ... )();
- pourquoi on doit écrire oElem.onclick = func; et pas oElem.onclick = func();
ou que sais-je encore... Disons qu'il faut rendre ta syntaxe la plus limpide possible.

a écrit :
Pour ce qui est de mon exemple de fonction anonyme, comme je l'ai précisé, il est simpliste. Pour ma part, j'utilise quelque chose de similaire à ce que tu as proposé, qui permet en effet d'isoler totalement le code et donc de ne pas craindre le code "tout pourri récupéré d'on ne sait où". Smiley cligne
C'est à dire ? As-tu un exemple moins simpliste ? ça m'intéresse... Smiley smile
Modérateur
Eldebaran a écrit :
Pour ce qui est du risque de collision avec d'autres bibliothèques, il n'est malheureusement jamais totalement nul avec Javascript, preuve en est l'exemple de l'une des versions de Prototype qui modifiait le prototype d'Object et faisait ainsi planter le code basé sur les boucles du type :
for (var i in obj) {}
Je te rejoins cependant sur le fait que, moins le risque d'interaction est grand, moins on court de risques.
Oui mais ce n'est pas de ton fait. C'est uniquement Prototype qui est en cause... et puis, tu peux reprendre la main en le redéfinissant toi aussi, non ? (Je dis peut-être une bêtise) Enfin... mieux vaut virer Prototype, c'est plus simple... Smiley ravi
Je pense que cette bibliothèque, bien qu'offrant de multiples possibilités, est loin d'être exempte d'erreurs... et on n'est pas obligé de les reproduire. Smiley smile
Salut,
koala64 a écrit :
En quoi ce n'est pas satisfaisant ? C'est justement le but recherché. Le plus gros risque provient surtout du code que tu ne maîtrises pas, c'est à dire, de celui des autres... Tu peux, pour toi, définir une interface accessible mais uniquement au sein de ta fonction anonyme car tu n'as aucun intérêt à rendre ton script accessible de l'extérieur.
Ce n'est pas satisfaisant dans le cas de l'exemple que j'utilise, c'est à dire dans celui d'une bibliothèque qui expose un certain nombre de fonctions à l'extérieur (ce qui reste quand même assez fréquent). Ceci dit, cette phrase est assez mal tournée, puisque ce sera en effet dans pas mal de cas au contraire très satisfaisant.
koala64 a écrit :
Cela peut s’avérer utile dans le cas d’une bibliothèque anonyme (dans le sens où aucun code extérieur n’en dépend) comme la suivante (elle aussi simpliste)
Cette phrase n'est pas juste. Comme dit précédemment, il existe encore des interactions à cause des gestionnaires d'événement onbidule... d'où l'intérêt d'apporter des précisions à ce sujet. Si tu as montré comment te protéger au mieux des autres, tu ne précises pas comment ne pas empiéter sur leur terrain alors que c'est tout aussi important... Si si, je t'assure, faut vivre en symbiose avec ses petits copains... Smiley cligne Certes, tu as raison. Ce que je voulais dire, c'est qu'aucun code extérieur n'en dépend au sens où aucun code extérieur n'a besoin d'accéder à une variable ou fonction de la bibliothèque. En fait, je pense que j'ai très mal choisi mon exemple. Smiley smile
koala64 a écrit :
Certes, ça va étendre un peu plus le champ d'action du tuto mais vu que le but principal est bien cette notion d'interaction, autant s'attacher à cette dernière plutôt qu'à décrire la technique hors contexte. Ca n'en sera que plus convaincant.
C'est vrai.
koala64 a écrit :
euh ben par exemple, la phrase suivante fait un peu mal à la tête... Smiley langue Ce n’est d’ailleurs pas étonnant si l’on sait que function f() {} est équivalent à var f = function() {}; (placé au début de la portée ou du fichier), et donc que la définition d’une fonction n’est qu’un raccourci pour la définition d’une variable faisant référence à cette fonction.
On a vite les bigoudis qui poussent. Smiley ravi Je pense que tu peux simplifier.Oui, en effet... Smiley sweatdrop
koala64 a écrit :
Oui par exemple mais tu peux aussi expliquer :
- pourquoi on doit écrire ( function() { ... } )(); et pas ( ... )();
- pourquoi on doit écrire oElem.onclick = func; et pas oElem.onclick = func();
ou que sais-je encore... Disons qu'il faut rendre ta syntaxe la plus limpide possible.
OK... Décidément, tu me donnes du boulot ! Smiley langue
koala64 a écrit :
C'est à dire ? As-tu un exemple moins simpliste ? ça m'intéresse... Smiley smile
Comme je te l'ai dit, c'est assez similaire à ce que tu as proposé. Voici un template de ce que j'utilise :

HTML (dans le <head>) :
<!--[if !IE]>--><script type="text/javascript" src="script.js"></script><!--<![[#0000]endif[/#]]-->
<!--[if IE]><script defer src="script.js"></script><![[#0000]endif[/#]]-->
Javascript :
if (document.getElementById && document.createTextNode) {
(function() {
	function init() {
		if (document.body && !init.done) {
			init.done = true;

			// Le code d'initialisation...
		}
	}

	function addLoadEvent(f) {
		if (document.addEventListener) {
			document.addEventListener("DOMContentLoaded", f, false);
		}

		if (window.addEventListener) {
			window.addEventListener("load", f, false);
		} else if (document.addEventListener) {
			document.addEventListener("load", f, false);
		} else if (window.attachEvent) {
			window.attachEvent("onload", f);
		}
	}

	/*@cc_on init();@*/
	addLoadEvent(init);
})();
}
Les commentaires conditionnels en HTML et en Javascript, ainsi que l'ajout de l'évènement "DOMContentLoaded" correspondent à mon adaptation de la méthode de Dean Edwards pour exécuter du code dès que l'arbre DOM a fini de se charger.

Si ce n'est pas clair, dis-le moi !

Merci en tout cas pour cette réponse très complète, il va falloir que je me mette à nouveau au boulot pour peaufiner le tutoriel.
Modifié par Eldebaran (14 Nov 2006 - 11:48)