IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Outils pour construire un code jQuery évolutif


précédentsommairesuivant

II. La fonction globale

II-A. Exemple d'une « news box »

II-A-1. Description

Il s'agit de la version adaptée en jQuery d'une « news box » proposée par MARCHA en réponse à cette question.

« News box » : diffusion verticale continue, de bas en haut, de messages (brefs, en principe) attirant l'attention sur de nouvelles informations. La courte pause avant la reprise de la diffusion indique au lecteur que la série est terminée.

Exemple n° 4 : « news box » sans fonction globale

 
Sélectionnez
(function($){
    var speed = 1;
    var offset = 5;
    var interval = 60;
    var pos;
    var pos_initial;
    
    function anim() {
        $("#newslist").css({
            visibility:"visible",
            top:Math.floor(pos)
        });
        
        pos -= speed;
        
        if(pos < (-1 * $("#newslist").height())) {
            pos = pos_initial;
        }
    }
     
    function startAnim() {
        pos_initial = $("#newsbox").height() + offset;
        pos = pos_initial;
        setInterval("anim()", interval);
    }
    
    $(this).ready(function(){
        $("#newsbox").hover(
            function(){
                speed = 0;
            },
            function(){
                speed = 1;
            }
        );
        
        startAnim()
    });
})(jQuery);

II-A-2. Bug !

Avec Firefox et l'extension Firebug, le programme s'interrompt sur l'erreur : « anim is not defined », car la fonction anim() est inaccessible.

Alors qu'en absence de clôture le programme donne entière satisfaction.

Je vous entends : « On nous agace avec la clôture et dès le premier véritable exemple rien ne va plus ! »

II-A-3. Pourquoi ?

La source de l'erreur est :
Sélectionnez
setInterval("anim()", interval);

Le problème vient de cette ligne de code qui demande à l'objet global « window » d'appeler la fonction anim() toutes les 60 millisecondes.

Or la fonction anim(), protégée par la clôture, est inaccessible pour l'objet global « window ».

II-A-4. Ouvrez la porte !

Hé oui ! Nous avons besoin d'un point d'entrée dans la clôture.

(3) Je cite3 :
« Je vous rappelle qu'en JavaScript tout fonctionne en se fondant sur des objets. (…) Le langage JavaScript permet de créer simplement un objet en se fondant sur l'objet Object ou en utilisant une forme littérale dont la syntaxe est décrite par la notation JSON. (…) Il est possible d'ajouter, de modifier et de supprimer les entrées de l'objet tout au long de sa vie. »

Extrait de la page 5 de la citation 3
Sélectionnez
var obj = new Object();

var obj = { ... };
// avec la notation JSON

obj["attribut"] = "valeur1";
// similaire à obj.attribut = "valeur1";
 
obj["methode"] = function(param1, param2) {
  ...
};
// similaire à obj.methode = function( ... ){ ... };

Fin de la citation3.

II-B. Exemple d'une « news box » utilisant une fonction globale

II-B-1. Fonction globale et objet global

Nous pouvons donc écrire la fonction anim() de la manière suivante :

 
Sélectionnez
var anim = function() { ... };

Mais nous devons omettre le mot clé « var » pour rendre anim() accessible depuis l'extérieur de la clôture.

C'est cette construction :

 
Sélectionnez
anim = function() { ... };

que j'appelle une fonction globale.

Un fragment de code existant rarement seul, je me servirai de la fonction globale ou de l'objet global :

 
Sélectionnez
monObjet = { ... };

comme point d'entrée permettant de communiquer avec la clôture.

II-B-2. Exemple

Exemple n° 5 : « news box » utilisant une fonction globale

 
Sélectionnez
(function($){
    var speed = 1;
    var offset = 5;
    var interval = 60;
    var pos;
    var pos_initial;
    
    anim = function() {
        $("#newslist").css({
            visibility:"visible",
            top:Math.floor(pos)
        });
        
        pos -= speed;
        
        if(pos < (-1 * $("#newslist").height())) {
            pos = pos_initial;
        }
    };
     
    function startAnim() {
        pos_initial = $("#newsbox").height() + offset;
        pos = pos_initial;
        setInterval("anim()", interval);
    }
    
    $(this).ready(function(){
        $("#newsbox").hover(
            function(){
                speed = 0;
            },
            function(){
                speed = 1;
            }
        );
        
        startAnim()
    });
})(jQuery);

Attention, dans la fonction

 
Sélectionnez
window.setInterval(expression, millisecondes);

expression peut s'écrire sous trois formes :

1. Un texte :

 
Sélectionnez
window.setInterval("anim()", 60);

2. Le nom de la fonction :

 
Sélectionnez
window.setInterval(anim, 60);

3. Une fonction anonyme :

 
Sélectionnez
window.setInterval(function(){anim();}, 60);

La forme 1 est la seule qui impose l'usage d'une fonction globale, car l'objet « window » convertit l'expression « anim() » en une recherche de la fonction window.anim() qu'il ne peut trouver lorsqu'elle est placée dans un espace privé.

Ce qui précède s'applique également à la fonction :

 
Sélectionnez
window.setTimeout(expression, millisecondes)

II-C. Pollution de l'espace de noms

En choisissant de promouvoir la clôture, espace privé, je souhaitais également libérer l'espace de noms « window », or chaque fonction globale ou objet global encombrera un peu plus cet espace de noms. De plus si comme il se doit, votre code est un composant réutilisable, le risque de collisions avec un autre composant du même nom est très élevé.

Il est clair que l'utilisation de la clôture implique l'usage d'un espace de noms privé.


précédentsommairesuivant