Skate in Mars

Aller au contenu | Aller au menu | Aller à la recherche

Programmation

Python, web, javascript... De longues nuits blanches en perspectives :)

Fil des billets - Fil des commentaires

mercredi 5 septembre 2007

Chaînage de méthodes en JavaScript

Lorsque l'on code en JavaScript (et dans bien d'autres langages), on se retrouve parfois avec des tartines de code qui utilisent plusieurs méthodes d'un même objet. Par exemple :

document.getElementById("infozone").className = "affiche";
document.getElementById("infozone").innerHTML = "Hello";
document.getElementById("infozone").style.display = "block";
(Exemple fictif, on ne devrait surtout pas utiliser .style.display et .innerHTML)
L'exemple est explicite, on va ajouter la classe affiche, insérer le texte "Hello" (et remplacer le HTML existant) et modifier la propriété CSS display de l'élément "infozone".
Ce genre de code est assez répétitif, mais heureusement les grandes librairies javascript nous permettent de gagner du temps grâce au chaînage de méthodes.
Comme son nom l'indique cela consiste à enchaîner les méhodes sur un même objet.

Pratique


Pour plus de clarté on va voir des exemples avec les bibliothèques Jquery, Mootools et Prototype pour réduire le code utilisé en exemple et le rendre plus propre.

1. Prototype


Inutile de présenter prototype, la bibliothèque utilisée par rails et une des plus mises en avant.
$() est un raccourci vers document.getElementById(), en plus d'étendre l'élément sélectionné en lui ajoutant des méthodes assez utiles (on peut également lui passer un élément html quelconque en argument pour profiter des méthodes étendues de prototype).

$("infozone").addClassName('affiche').update("Hello").show();

Quelques améliorations : addClassName nous permet de conserver les classes deja existantes de l'élément et update permet de nettoyer le html inséré.

2. Mootools


Mootools est une librairie pas tellement connue mais rapide et légère et est assez puissante au niveau des effets que l'on peut utiliser. On peut également choisir de télécharger seulement quelques éléments de la lib pour encore alléger le tout.

$("infozone").addClass("affiche").setText("Hello").setStyle('display', 'block');

La méthode d'ajout d'une classe est plus claire que pour prototype, par contre il n'y a pas de méthodes du genre show() ou hide() (c'est un choix des développeurs qui estiment que setStyle fait son boulot).

3. Jquery


Jquery est une bibliothèque assez à la mode en ce moment et qui a justement popularisé le concept de chaînage de méthodes car il repose essentiellement sur ce concept comme le montre le site et les démos.

$("#infozone").addClass("affiche").text("Hello").show();

La grande différence est visible dans la fonction $ qui contrairement aux autres libs est utilisé avec des sélecteurs (ici on utilise le sélecteur CSS "#" qui identifie l'id d'un élément). On peut également utiliser des sélecteurs CSS3 ou XPath. Prototype et Mootools utilisent tous deux la fonction $$() pour cet usage.
La fonction text est aussi assez différente car elle est utilisée de deux manières : appelée avec un argument elle se comporte comme update() ou setText(), mais si on l'appelle sans argument elle renverra le texte de l'élément (auquel sera retiré les balises HTML).

Comment ca marche ?


Le principe est en fait très simple.
Chacune des méthodes que l'on a vu renvoie l'élément sur lequel elle a été appliquée.
Voici par exemple le code de la méthode Element.hide de prototype :

hide: function(element) {
 $(element).style.display = 'none';
 return element; // <-- la magic touch
},


C'est donc sur cet élément que l'on va appliquer la prochaine méthode de notre chaîne de fonction.

Pour aller plus loin, vous pouvez également lire mon précédent article "
Des sous-menus déroulants non obstrusifs avec Jquery" ou l'on peut voir l'utilisation du chaînage de méthode pour gagner en clarté et en taille dans un script non-obstrusif, en plus de se déplacer dans le DOM :
$(this).parent().parent().children("li").find("ul.montre").slideToggle("").removeClass("montre").addClass("matched");

PS : J'espère que cet article vous aura donné envie d'utiliser une des nombreuses bibliothèques Javascript mises à disposition, sinon, voici 6 raisons pour le faire.

mercredi 6 juin 2007

Des sous-menus déroulants non obstrusifs avec Jquery


Lors de mon stage, j'ai dû réaliser le prototype d'une page d'accueil qui comprenait plusieurs rubriques et sous-menus.
Le nombre d'éléments à présenter étant trop important il fallait cacher les sous-menus et les afficher à la demande.
Le tout devant être non obstrusif j'ai finalement décidé d'utiliser Jquery pour réaliser des menus déroulants.

La solution est ainsi très élégante et ne requiert que peu de Javascript. Le balisage HTML reste également très propre et valide même si on peut encore améliorer ce côté-ci.
Analysons ce dernier :

<div id="menus">
    <div id="enfants">
        <h2>Accueil d'enfants</h2>
        <ul>
            <li id="enfants_da">
                <a href="#">Déficients auditifs</a>
                <ul>
                    <li><a href="#">Centre 1</a></li>
                    <li><a href="#">Centre 2</a></li>
                    <li><a href="#">Centre 3</a></li>
                </ul>
            </li>
            <li>
                <a href="#">Déficients visuels</a>
                <ul id="enfants_dv">
                    <li><a href="#">Centre 1b</a></li>
                    <li><a href="#">Centre 2b</a></li>
                    <li><a href="#">Centre 3b</a></li>
                </ul>
            </li>
        </ul>
    </div>

    <div id="adultes">
    <!-- Même balisage que pour les enfants -->
    </div>
</div>


Par défaut on doit voir uniquement le titre de la rubrique (le <h2>) ainsi que les liens.
Le tout doit également être visible avec un navigateur ayant le javascript désactivé mais utilisant les CSS, on ne va donc pas utiliser directement ceux-ci pour cacher le <ul> des sous-rubriques.

Voici le code javascript qui utilise donc Jquery.

<script type="text/javascript">
    $(document).ready(function(){

    $("#menus div ul ul").hide();
    $("#menus div ul ul ul").show(); //sous-sous-menus

    $("#menus div ul li a").click(function(){
        $(this).parent().parent().children("li").find("ul.montre").slideToggle("").removeClass("montre").addClass("matched");
        $(this).parent().children("ul").not(".matched").addClass("montre").slideToggle("slow");
        $(this).parent().parent().children("li").find("ul.matched").removeClass("matched");
        if ($(this).attr("href") == "#") {
            return false;
        }
    });

    }); //fin onready
</script>

    
Notez que ce code suffit pour _tous_ les menus (les <div id="enfants">, <div id="adultes"> etc).
Le tout est donc assez compact et élégant en plus d'être adaptable facilement.

Commencons par la fonction de base à utiliser : $(document).ready();
Le paramètre à passer à cette fonction est une fonction qui sera appelée lorsque le DOM sera prêt (entre le chargement du HTML et celui des éléments externes tels que les images).
Remarquez si vous ne le saviez pas que Javascript nous permet d'utiliser ici une fonction anonyme : function(){} en paramètre, ce qui évite de créer la fonction ailleurs.

Le code commence donc réellement à l'intérieur de cette fonction.
La première ligne permet de cacher les sous-menus. La fonction $() retourne les éléments Jquery qui correspondent aux sélecteurs demandés en paramètre. On peut utiliser comme ici du CSS mais aussi Xpath par exemple.
Cette fonction est comparable à la fonction $$() de Prototype.
On applique donc ici la méthode hide() à tous ces éléments. Tous les sous-menus seront ainsi cachés (facile non ? :) ).
La deuxième ligne est necesaire pour éviter aux sous-sous-menus (des <ul> dans les <ul> des centres, ici cela peut-être des services internes d'un centre) de rester constamment cachés à cause de la première règle.

Passons donc au coeur de la technique avec la fonction suivante. Ici on applique à tous les liens une méthode qui permet de leur associer une action lors d'un clic (au lieu d'utiliser onclick directement dans le HTML).
Comme pour le $(document).ready(); on passe une fonction anonyme en paramètre qui représentera l'action à effectuer.

La première ligne de cette fonction montre la particularité de Jquery qui est le chaînage des méthodes. Chaque méthode renvoie en effet l'élément sur lequel il agit.
Le $(this) représente ici l'élement sur lequel on greffe l'evènement, c'est donc la balise <a> dans notre cas.
Les deux parent() permettent de remonter dans le DOM : on se retrouve donc à agir sur la balise (on devrait parler de noeud plus exactement) <ul>.
Avec children("li") on peut voir que Jquery va gérer sans problème le fait que l'on se retrouve avec plusieurs éléments.
find() permet ensuite de 'trier' les éléments trouvés, ici un <ul> qui possède la classe montre.
On applique ensuite la méthode slideToggle() qui est celle qui permet d'obtenir l'effet de menu déroulant (voir la démo sur le site de Jquery).
On enlève ensuite la classe "montre" avec une simple méthode.

La deuxième ligne est celle qui va montrer le sous-menu demandé (le <ul> présent dans le même <li> que le lien) et y ajouter la classe montre.
La troisième enlève la classe "matched" à tous les éléments qui la possédaient auparavant.

Un peu d'explications : les éléments montrés se voient ici appliqués la classe "montre" ce qui permet de savoir quels éléments sont affichés ou non.
En effet on souhaite n'afficher qu'un seul sous-menu à la fois, il faut donc cacher les sous-menus déjà montrés (ceux qui possèdent la classe montre).
La classe matched permet d'éviter de cacher puis remontrer directement un sous-menu sur lequel on a cliqué deux fois :
en effet, on peut imaginer que si l'utilisateur clique sur un sous-menu une deuxième fois ce sera pour le cacher.
On trie donc dans la règle d'affichage les éléments matched car on sait que ceux-ci ont déjà été cachés. On enlève ensuite cette classe pour éviter des problèmes à la prochaine utilisation.

Le dernier test permet de renvoyer false si le lien a pour cible '#'. Cela permet de ne pas remonter en haut de la page, mais laisse la possibilité d'utiliser de vrais liens dans le menus (si l'on ne souhaite pas de sous-menus dans une partie précise).

C'est tout ! Je ne propose pas de capture d'écran ou de démo, la page étant pour le moment utilisée uniquement dans l'association ou je réliase le stage, mais voici le css que j'utilise :

#menus {
margin-left: 20px;
overflow-y: auto;
overflow-x: hidden;
font-size: 14px;
font-family: Verdana, sans-serif;
font-weight: bold;
color: #456b90;
height: 700px;
}
#menus a {
text-decoration: none;
}
#menus div {
position: absolute;
margin-top: 10px;
}
#menus div ul {
width: 150px;
margin-top: 0px;
margin-left: 0;
padding-left: 20px;
background-color: #FFFFFF;
}
#menus div h2 {
font-size: 19px;
font-family: "Trebuchet MS", sans-serif;
margin-bottom: 7px;
}
#menus div ul li p {
margin: 1px;
padding: 4px;
}
#menus div ul li ul {
background-color: #75b9e4;
padding: 4px;
font-size: 12px;
font-weight: normal;
list-style-type: none;
margin: 0;
}

#enfants {
left: 700px;
top: 30px;
}
#enfants h2 {
color: #6be32f;
}


Chaque sous-partie (enfants, adultes) est positionnée de manière absolue dans la page avec left et top.

On peut donc conclure en affirmant sans problèmes que Jquery permet de réaliser plusieurs effets graphiques dans la page, de manière assez simple et surtout en restant accessible et non obstrusif :)

J'ai peu parlé de Jquery, on aurait pourtant pu dire que la lib est légère (une version compréssée étant de plus disponible), rapide, bref un bon candidat au remplacement de Prototype. Voici quelques liens comme d'habitude :)

dimanche 3 décembre 2006

Quelques liens divers et intéressants

Ok, ça fait quasiment un mois que j'ai pas bloggué, je vais donc tout de même prendre 10 minutes à écrire ce billet avec un titre assez pourri, il faut le dire... Voici donc simplement une petite liste de liens que j'ai trouvé intéressants à lire au cours de ces dernières semaines. J'avoue que cela fait un peu presse-papier, mais bon, c'est mon blog après tout !

http://www.cs.rit.edu/~atk/Java/Sorting/sorting.html Java inside. 4 implémentations de différents algorithmes de tri. De petites animations sympa sont la pour illustrer le tout :).

http://www.openbsd101.com/installation.html Le lien parle de lui-même, un howto pour installer un OpenBSD dont la version 4.0 est sortie il y a peu.

http://freebsd.bebik.net/wiki/index.php/Accueil Une source de docs en français sur FreeBSD.

http://www.smashingmagazine.com/2006/11/11/css-based-forms-modern-solutions/ Des formulaires beaux et accessibles.

http://www.unixwiz.net/techtips/iguide-crypto-hashes.html Md5 ? Hashes ? Checksum. Une page à lire pour comprendre l'utilité des algorithmes de hash.

http://standblog.org/blog/post/2006/11/20/93114958-le-livre-bien-developper-pour-le-web-20 Un livre sur le Web 2.0 préfacé par Tristan Nitot. Ok le Web 2.0 c'est kikoolol vous dites-vous, et bien pas du tout, et de tels livres vous prouverons le contraire. Celui la est sur ma lettre au papa noel :) (une interview en flash de l'auteur est également disponible).

mercredi 8 novembre 2006

Projet Tamarin : Adobe donne sa machine virtuelle ECMAscript à Mozilla

Adobe, qui a racheté il y a peu Macromédia, le créateur de Flash, vient de libérer le code (135000 lignes) de sa machine virtuelle ECMAscript 4 sous licence Mozilla Public Licence. Cela en fait donc un produit open source, nommé Tamarin.

A quoi sert cette VM ?
ECMAscript, bientôt en version 4 (la spécification est à l'état de brouillon mais est en phase de finalisation) est le langage sur lequel se base Javascript (la future version 2 est celle respectant ECMAscript 4) ainsi que Actionscript (version 3, celle utilisée dans le flash player version 9). ActionScript est le langage utilisé pour coder des scripts flash.

Cela ne veut pas pour autant dire que le lecteur flash sera bientôt libre, mais la machine virtuelle en est néanmoins un point très important. On peut donc déjà espérer une disponibilité sur plus de plate-formes, notamment amd64 pour laquelle le portage de cette VM est en cours.

En plus de gagner du temps en n'ayant pas à adapter son précédent moteur Javascript (nommée SpiderMonkey) pour Javascript 2 depuis Javascript 1.7 utilisé dans firefox 2, le premier gain pour le projet Mozilla, qui utilise Javascript non seulement dans ses pages Web mais également pour toutes ses interfaces (à travers XUL), se situe au niveau des performances, la VM étant très rapide et intégrant des technologies intéressantes (comme un système de ramasse-miettes que je ne comprends pas moi même ;) ).

Un autre avantage de cette libération est la réunion d'efforts. On peut imaginer que d'autres navigateurs comme Konqueror pourront reprendre cette VM pour la réutiliser. Ce qui amènerait donc à du Javascript encore plus standard entre les navigateurs, ce qui est toujours une bonne nouvelle.

Mais le plus gros avantage que l'on pourrait tirer de cette machine virtuelle est son utilisation en Just In Time.
Pour expliquer ce concept, rappelons que le Javascript est un langage interprété, comme Java ou python. Pour que la machine comprenne ce code, il n'y a pas de phase de compilation comme en C, mais une phase de conversion en bytecode, qui est plus proche de la machine. Pour python par exemple cela se traduit par une génération de fichiers .pyc à partir des fichiers .py, qui seront reutilisés ensuite au lieu de reinterpreter le .py originel.
Le problème du bytecode est qu'il doit encore être interprété par une machine virtuelle, et c'est pourquoi les langages interprétés sont plus lents que les langages compilés. Javascript est encore plus lent dans un navigateur car le moteur JS, à chaque utilisation d'une fonction, va reformer du bytecode pour le réinterpréter ensuite, ce qui est une grosse perte de temps et donc de performances.

Avec la machine virtuelle d'Adobe, on peut utiliser directement du bytecode deja présent dans un fichier, comme le fait deja le flash player avec les fichiers .swf, ce qui entraine une première hausse des performances.

Mais la VM D'Adobe permet également de faire du Just-In-Time : au lieu de générer tout le langage machine à partir du bytecode lors de l'interpretation, la machine virtuelle ne "convertira" que les parties du code réellement utilisées lors de l'exécution du script, d'ou un deuxième gain de performance.

Pour finir sachez que le résultat de cette libération ne se verra pas avant 2008 d'après La fondation Mozilla, et donc après Firefox 3 qui lui est prévu pour 2007.

Pour finir, des liens plus ou moins techniques pour mieux comprendre :
Un article sur linuxfr.org
Article sur vnunet, plutôt orienté économie, à mettre en relation avec l'article de Fred Cavazza.
Deux articles wikipedia sur ECMAScript et le système de JIT.

Enfin, les articles les plus clairs bien qu'en anglais :
Celui d'un developpeur de flash : http://www.kaourantin.net/2006/11/spidermonkeys-relative-tamarin-joins.html
Et celui d'un responsable de la fondation Mozilla : http://hecker.org/mozilla/adobe-mozilla-and-tamarin.
Bonne lecture ;)

vendredi 8 septembre 2006

D'une pierre deux coups avec Google Image Labeler

Voici Google Image Labeler : http://images.google.com/imagelabeler/, une curiosité que j'ai découvert il y a peu.

Le principe est simple : vous jouez à deux. Une image vous est montrée. Vous devez entrez une description pour cette image. Par exemple, un oiseau. Vous entrerez donc "bird" vu que le jeu se déroule en anglais.

Vous pouvez entrez plusieurs mots, et lorsque les deux participants ont entré le même, vous gagnez un certain nombre de points, et on passe à une autre image

Le jeu dure 90 secondes. Si vous ne trouvez pas de définition identique pour une image, vous pouvez proposer à votre partenaire de passer.

Le tout utilise donc javascript et les technos Ajax, mais cela reste très fluide et bien pensé.

Le deuxième côté interressant, c'est que ce n'est pas un simple jeu, car google se sert des resultats pour rendre sa recherche d'images plus pertinente.
Voila donc une idée interressante.

On peut participer sans avoir besoin d'un compte gmail mais il peut être utilisé pour garder une trace de ses scores totaux. J'y ai joué quelques fois et on trouve très vite un partenaire.
Un dernier conseil si vous vous lancez, pensez à utiliser des mots très simples pour aller plus vite : man, car, couple, etc...
Bon jeu !

dimanche 6 août 2006

Interview de divers programmeurs

Voici un article interressant qui est passé sur mon agregateur, il s'agit d'un recueil de quelques questions posées à divers programmeurs celèbres et fameux.

Lire la suite...

lundi 17 juillet 2006

Les fichiers de config en python

Je republie ce billet qui était présent sur l'ancien blog car pas mal de recherches google mènent des gens ici après des recherches sur le sujet :)

Lire la suite...