OVH Cloud OVH Cloud

Au secours !

12 réponses
Avatar
fred
Bonjour,

ne tombez pas à la renverse en voyant la simplicité de ma question, mais je
n'y arrive vraiment pas...
Dans l'exemple ci-dessous, je ne comprends pas pourquoi ma "fonctionA" n'est
pas appelée au chargement de la page

<body>
<script language="javascript">
function fonctionA() {
alert('fonctionA');
}

function init() {
alert('init');
fonctionA;
}

window.onload = init;
</script>
</body>

Mon objectif initial était d'appeler successivement 2 fonctions au
chargement de la page (une fonction perso "fonctionA" définie dans le "body"
et une fonction d'une librairie externe (fonctionB) déclarée dans un autre
fichier .js). J'avais donc essayé de définir la fonction init:
function init() {
fonctionA;
fonctionB;
}
appelée sur l'événement onload:
window.onload = init;
mais ça ne marche pas... Sauriez-vous comment faire ?

Un grand merci.

Fred.

10 réponses

1 2
Avatar
Tony
Essaye avec des parenthèses :

function init() {
alert('init');
fonctionA();
}


window.onload = init();

========================= ==================


Bonjour,

ne tombez pas à la renverse en voyant la simplicité de ma question, m ais je
n'y arrive vraiment pas...
Dans l'exemple ci-dessous, je ne comprends pas pourquoi ma "fonctionA" n' est
pas appelée au chargement de la page

<body>
<script language="javascript">
function fonctionA() {
alert('fonctionA');
}

function init() {
alert('init');
fonctionA;
}

window.onload = init;
</script>
</body>

Mon objectif initial était d'appeler successivement 2 fonctions au
chargement de la page (une fonction perso "fonctionA" définie dans le " body"
et une fonction d'une librairie externe (fonctionB) déclarée dans un autre
fichier .js). J'avais donc essayé de définir la fonction init:
function init() {
fonctionA;
fonctionB;
}
appelée sur l'événement onload:
window.onload = init;
mais ça ne marche pas... Sauriez-vous comment faire ?

Un grand merci.

Fred.


Avatar
Laurent vilday
Essaye avec des parenthèses :

function init() {
alert('init');
fonctionA();
}


window.onload = init();


Surtout pas malheureux. La parenthèse est très loin d'être la réponse
universelle aux "problème" JS.

fonctionA();
ok, pas de problème on veut que ca s'execute

window.onload = init();
Surtout pas. Jamais. Avec des parenthèses on est dans le cas de
l'execution immédiate d'une fonction. Hors ce qu'on veut ici c'est
associer la référence de la fonction "init" au onload. Donc ce sera ici
sans les parenthèses.

function init()
{
alert('init');
fonctionA();
}

window.onload = init;

Pour se convaincre que maFunct !== maFunct(), il suffit de quelques
lignes de test :

function maFunct()
{
return 'je suis un texte';
}

alert( typeof maFunct)
==> ça écrit "function", c'est bien ce qui est attendu, on a bien testé
le type de la function donc sa référence.

alert( typeof maFunct() )
==> ça écrit "string", c'est évidemment pas une fonction qu'on a testé à
causes des parenthèses, ce qu'on a testé là c'est le resultat de la
function.

--
laurent

Avatar
Laurent vilday
Dans l'exemple ci-dessous, je ne comprends pas pourquoi ma "fonctionA" n'est
pas appelée au chargement de la page

<body>
<script language="javascript">
function fonctionA() {
alert('fonctionA');
}

function init() {
alert('init');
fonctionA;
}

window.onload = init;
</script>
</body>

Mon objectif initial était d'appeler successivement 2 fonctions au
chargement de la page (une fonction perso "fonctionA" définie dans le "body"
et une fonction d'une librairie externe (fonctionB) déclarée dans un autre
fichier .js).


Pour exécuter une fonction, il faut faire : maFunction();

Pour obtenir la référence (pour faire simple, une sorte d'adresse
mémoire) d'une fonction, il faut squizzer les parenthèses : maFunction;

Dans la fonction init(), puisque tu veux que fonctionA et fonctionB
s'exécute, il faut les parenthèses :

function init()
{
fonctionA();
fonctionB();
}

Pour la déclaration onload, il ne faut surtout *pas* que la fonction
init soit exécutée immédiatement mais seulement lorsque l'objet *window*
déclenchera sa fonction onload() - qu'on ne controle pas -, on ne veut
donc associer que la référence de init à la référence de window.onload :

window.onload = init;

Plûtot que de t'embêter a déclarer des fonctions intermédiaires, je te
conseille d'utiliser une librairie générique de chargement (la tienne de
librairie hein, pas les saloperies qui existent sur le web et qui sont
censées faire tout à ta place mais qui t'empecheront de comprendre ce
qui se passe, comment ça se passe et surtout pourquoi).

Qqchose comme la "librairie" de chargement ci-dessous (comme d'hab, le
code fourni n'est là qu'à titre d'idée générique de fonctionnement, ce
n'est *absolument pas* à copier/coller tel quel sans comprendre -
D'autant plus que si on commence par là, on finit par arriver sur une
gestion du onunload, puis du onbeforeunload et hop tant qu'on y est on
se retrouve à gérer tous les évènements :)

/**
* Loader générique
* @param {object} F Function1 reference
*/
function Loader(F)
{
// index du listener qu'on ajoute
var I = Loader.listeners.length;
Loader.listeners[I] = F;
}
// Listeners
Loader.listeners = [];
// Fonction executée sur le onload
Loader.init = function(evt)
{
for ( var i = 0, m = Loader.listeners; i++ )
{
var F = Loader.listeners[i];
F(evt);
}
}
window.onload = Loader.init;

Ainsi, plutot que de définir des fonctions intérmédiaires de chargement
sur chacune de tes pages, il te suffit d'appeler Loader().

Comme dit précédemment, il faudra encore enlever les parenthèses puisque
on veut seulement la référence.

function fonctionA() { alert('A'); }
function fonctionB() { alert('B'); }

Loader(fonctionA);
Loader(fonctionB);

Si tu as besoin de plus "d'explications" ou d'un petit exemple,
n'hésites pas à faire signe ici, il y a plein de bonnes âmes prêtent à
te donner le coup de pouce nécessaire.

--
laurent

Avatar
Florian Sinatra
*Laurent vilday* @ 25/08/2006 14:12 :
/**
* Loader générique
* @param {object} F Function1 reference
*/
function Loader(F)
{
// index du listener qu'on ajoute
var I = Loader.listeners.length;
Loader.listeners[I] = F;
}
// Listeners
Loader.listeners = [];


là tu ajoutes un objet à une fonction ? c'est une histoire de prototypes
et de constructeur non ?

// Fonction executée sur le onload
Loader.init = function(evt)


quel est cet argument evt ? où est-il passé à la fonction après ?

{
for ( var i = 0, m = Loader.listeners; i++ )


d'où vient ce m ? ce serait pas plutôt i = Loader.listeners.length ?

{
var F = Loader.listeners[i];
F(evt);


même question.

}
}
window.onload = Loader.init;

function fonctionA() { alert('A'); }
function fonctionB() { alert('B'); }

Loader(fonctionA);
Loader(fonctionB);


est-il possible de passer des arguments à ces fonctions ?

Si tu as besoin de plus "d'explications" ou d'un petit exemple,
n'hésites pas à faire signe ici, il y a plein de bonnes âmes prêtent à
te donner le coup de pouce nécessaire.


Javascript restera toujours mystérieux pour moi...

Avatar
fred
Pour exécuter une fonction, il faut faire : maFunction();

Pour obtenir la référence (pour faire simple, une sorte d'adresse mémoire)
d'une fonction, il faut squizzer les parenthèses : maFunction;


Impeccable, je confondais les deux, maintenant tout est clair.
Merci beaucoup pour ta réponse élaborée !

Fred.

Avatar
ASM

Plûtot que de t'embêter a déclarer des fonctions intermédiaires, je te
conseille d'utiliser une librairie générique de chargement (la tienne de
librairie hein, pas les saloperies qui existent sur le web


Ha ! oui ! exemple interressant.

Mais comme mon dernier neurone est fatigué et n'est pas fichu de se
souvenir de sa 'tite Lib home hand made


window.onload = function() {

// instructions 1 :
if(confirm('Voulez-vous voir cette page?nnon = [Annuler]'))
alert('Bon, alors OKnJe la laisse');
else
{
var d = document;
d.open();
d.write('<html><h1>Page vid&eacute;<h1><html>')
d.close();
alert('La page est videnOu presque.');
}

// instructions 2 :
if(prompt('couleur cheval blanc Henri IV ?').toLowerCase()=='blanc')
alert('correct');
else
alert('faux');

// instructions 3 :
alert('fonction 3 :nfin des tests');
}

ou :

function A() {
if(confirm('Voulez-vous voir cette page?nnon = [Annuler]'))
alert('Bon, alors OKnJe la laisse');
else
{
var d = document;
d.open();
d.write('<html><h1>Page vid&eacute;<h1><html>')
d.close();
alert('La page est vide !n... ou presque.');
}
}
function B() {
if(prompt('couleur cheval blanc Henri IV ?').toLowerCase()=='blanc')
alert('correct');
else
alert('faux');
}
function C() {
alert('fonction 3 :nfin des tests');
}
window.onload = function() { A(); B(); C(); };

--
Stephane Moriaux et son [moins] vieux Mac

Avatar
ASM
*Laurent vilday* @ 25/08/2006 14:12 :
{
for ( var i = 0, m = Loader.listeners; i++ )


d'où vient ce m ? ce serait pas plutôt i = Loader.listeners.length ?


for ( var i = 0, m = Loader.listeners; i<m.length; i++ )

Sans doute ?


et pour les arguments :

function fonctionArgts(x) { alert(x); }

Loader(fonctionArgts('Z'));
Loader(alert('Y'));

Je suppose ?

--
Stephane Moriaux et son [moins] vieux Mac


Avatar
Laurent vilday
*Laurent vilday* @ 25/08/2006 14:12 :
/**
* Loader générique
* @param {object} F Function1 reference
*/
function Loader(F)
{
// index du listener qu'on ajoute
var I = Loader.listeners.length;
Loader.listeners[I] = F;
}
// Listeners
Loader.listeners = [];


là tu ajoutes un objet à une fonction ? c'est une histoire de prototypes
et de constructeur non ?


Non, pas ici. La c'est l'ajout d'une propriété à un objet, une fonction
étant un objet. De la même façon qu'on ajoute une propriété à n'importe
quel objet.

var monObjet = {foo:true, bar:false};
monObjet.foobar = 'texte';

var monInt = 25;
monInt.valid = false;

var monString = 'foobar';
monString.prop = 'foo';

Les "constructeurs" (existent pas en js) et le prototype permet de créer
des méthodes à l'instance d'un objet.

function maFunc() { alert('init'); }
maFunc.prototype.foo = function()
{
// je suis dans le prototype
alert(this);
};
maFunc.bar = function()
{
// je suis hors du prototype
alert(this);
}

// on instancie l'objet
var instance = new maFunc();

// on appelle la fonction foo() du prototype
instance.foo();

// on appelle la fonction bar() de l'objet
maFunc.bar();

// il est impossible d'appeler bar() depuis l'instance
// cette ligne provoque une erreur d'execution :
// function bar is undefined
instance.bar(); // INTERDIT

// Fonction executée sur le onload
Loader.init = function(evt)


quel est cet argument evt ? où est-il passé à la fonction après ?


lorsque l'on fait window.onload = maFunction, on associe l'évènement
load de l'objet window à la référence maFunction. Lorsque l'évènement
est déclenché par le navigateur, celui-ci fourni un paramètre à la
fonction qui se trouve être la représentation de l'event. Hormis IE,
mais là il faudra voir les archives, on en a déjà pas mal parlé, et
surtout il faut lire ça je pense :
http://www.quirksmode.org/js/events_tradmod.html ainsi que toutes les
pages autour concernant les events.

Ceci dit, mea culpa, j'aurai pas du l'utiliser ici dans "l'exemple". Ca
prête à confusion, désolé, inutile dans cet "exemple".

{
for ( var i = 0, m = Loader.listeners; i++ )


d'où vient ce m ? ce serait pas plutôt i = Loader.listeners.length ?


Argg grr et reargg, je me suis relu pourtant. Ca m'apprendra à pas
tester, maxi mea culpa (dis donc) . ok la bonne ligne c'est ça :

for ( var i = 0, m = Loader.listeners.length; i < m; i++ )

ou encore

for ( var i = 0; i < Loader.listeners.length; i++ )

Je préfère la première forme parce que ça évite au navigateur de
"recalculer" la limite maximale à chaque itération de la boucle, mais
c'est pareil en fait, c'est qu'une question de préférence d'écriture. On
a tous nos petites manies de codage :p

[snip]

Loader(fonctionA);
Loader(fonctionB);


est-il possible de passer des arguments à ces fonctions ?


Dans l'état non. Mais oui, pourquoi pas, et comme je disais c'est qu'une
"direction", en ajoutant la gestion d'un objet arbitraire en paramètre,
on en vient vite à vouloir controler plein d'autres types d'events, les
scopes d'execution, etc.

/**
* Loader générique
* @param {object} F Function1 reference
* @param {object} O Objet arbitraire fourni au callback
*/
function Loader(F, O)
{
// index du listener qu'on ajoute
var I = Loader.listeners.length;
Loader.listeners[I] = [F, O];
}
// Listeners
Loader.listeners = [];
// Fonction executée sur le onload
Loader.init = function()
{
for ( var i = 0, m = Loader.listeners.length; i < m; i++ )
{
var F = Loader.listeners[i][0];
var O = Loader.listeners[i][1];
F(O);
}
}
window.onload = Loader.init;

function fonctionA(param) { alert('fonctionA ' + param); }
function fonctionB(param) { alert('fonctionB ' + param); }

Loader(fonctionA, 'param1');
Loader(fonctionB, 'param2');

Et cette fois c'est testé :D
http://mokhet.com/tests/loader.html

Javascript restera toujours mystérieux pour moi...


Je crois que ce qui est mystérieux, c'est principalement l'idée qu'on
s'en fait et le fait qu'il n'existe pas, à ma connaissance, de
documentation claire en français.

Les différences d'implémentation entre les navigateurs n'aident pas à
démystifier le langage évidemment :D

Vala, j'espère que c'est un peu plus clair.

--
laurent


Avatar
Laurent vilday
*Laurent vilday* @ 25/08/2006 14:12 :
{
for ( var i = 0, m = Loader.listeners; i++ )


d'où vient ce m ? ce serait pas plutôt i = Loader.listeners.length ?


for ( var i = 0, m = Loader.listeners; i<m.length; i++ )

Sans doute ?


qqchose dans le genre oui :p cf ma réponse à Florian.

et pour les arguments :

function fonctionArgts(x) { alert(x); }

Loader(fonctionArgts('Z'));
Loader(alert('Y'));

Je suppose ?


Nope, avec cette notation on retombe sur le problème de l'execution de
la fonction alors qu'on ne veut que sa référence.

Loader(fonctionArgts, 'Z');
Loader(alert, 'Y');

--
laurent



Avatar
Florian Sinatra
*ASM* @ 25/08/2006 16:18 :
*Laurent vilday* @ 25/08/2006 14:12 :
{
for ( var i = 0, m = Loader.listeners; i++ )
d'où vient ce m ? ce serait pas plutôt i = Loader.listeners.length ?




je voulais dire i < Loader.listeners.length

for ( var i = 0, m = Loader.listeners; i<m.length; i++ )

Sans doute ?


ce qui revient au même, mais en passant par m

et pour les arguments :

function fonctionArgts(x) { alert(x); }

Loader(fonctionArgts('Z'));
Loader(alert('Y'));

Je suppose ?


dans ce cas, ce n'est plus une référence sur la fonction mais sur ce
qu'elle retourne, dans ce cas l'exécution d'une alert, qui est ajoutée
au tableau Loader.listeners, et je doute que ca puisse fonctionner...



1 2