La version 1.7 de prototype (en release candidate) en plus de corrections de différents bugs, et d'optimisations, apporte de nouveaux outils qui vont grandement nous simplifier la vie. Je vous propose de les découvrir
1. La méthode measure
Elle permet de récupérer une valeur de propriété css calculée exprimée en pixels et nous la renvoie en nombre, ce qui est bien pratique pour faire des calculs : plus besoin de supprimer px, de tester le isNaN et de faire un parse ; prototype s'occupe de tout
Donc nous avons là un exemple avec la bordure, mais on peut bien sur remplacer la clé "border-bottom" les autres clés qui nous permettent d'avoir différentes infos.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 <div id="superparent" class="parent"> <div id="parent" class="parent"> <div id="unElement" style="border-style:solid;border-color:black;border-width:1px 2px 3px 0;padding:2px 4px 1px 0;margin:0 5px 0 5px;width:100px;height:80px;"> </div> </div> </div> <script type="text/javascript"> // Avant : alert($("unElement").getStyle("border-bottom-width")); // --> 3px // Avec prototype 1.7 alert($("unElement").measure("border-bottom")); // --> 3 </script>
La méthode measure est sympathique, mais l'utilité de récupérer la largeur de la bordure de gauche est assez limitée... le besoin le plus évident de mesurer ainsi des propriétés à lieu quand on cherche à calculer l'espace occupé par un élément. Mais dans ce cas, on se voit mal écrire :
Bien que ca fonctionne. Pour nous faciliter la vie, il existe donc des propriétés magiques pour obtenir l'occupation de la boite :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 var elem = $("unElement"); var widthTotaleOccupee = elem.measure("margin-left") + elem.measure("border-left") + elem.measure("padding-left") + elem.measure("width") + elem.measure("padding-right") + elem.measure("border-right") + elem.measure("margin-left"); alert(widthTotaleOccupee);
margin-box-width nous donnera donc marges + bordures + padding + width;
de la même façon, nous avons margin-box-height, mais aussi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 var elem = $("unElement"); var widthTotaleOccupee = elem.measure("margin-box-width"); alert(widthTotaleOccupee);
- border-box-width et border-box-height qui donneront la taille de la boite jusqu'aux bordures (sans les marges donc)
- et vous l'aviez deviné,padding-box-width et padding-box-height la taille de la boite avec le padding(sans les marges, ni les bordures).
Voilà qui va simplifier et rendre plus lisible pas mal de code.
A noter que dans le cas de marges négatives, 0 est renvoyé. On sent bien ici que l'idée est de calculer l'espace occupé par un élément.
Comme tout cela ne suffisait pas, un nouvel objet a fait son apparition pour englober toutes ces notions :
2. Element.Layout.
Plutot que de mesurer à chaque fois, on peut demander le layout d'un élément, puis piocher au fur et à mesure de nos besoins dans ces propriétés:
A noter que par défaut, les propriétés sont chargées en mode lazy, donc pas de calcule avant d'en avoir besoin (sauf si on passe true à getLayout); de plus elles sont mises en cache, ce qui signifie qu'elles ne sont plus recalculées. Attention cependant, si entre 2 appels, les attributs de styles ont changés, il faut re-demander une instance de layout, l'ancienne étant obsolète.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 var elem = $("unElement"); var elemLayout = elem.getLayout(); alert(elemLayout.get("margin-box-width"));
Il existe également une méthode getCSS sur Element.Layout qui permettrai de récupérer le layout en une chaîne css. Je mets au conditionnel car je n'ai pas réussi à la faire fonctionner ... c'est une RC...
3. Gestion des événements
La gestion des événements a été encore simplifiée. Il existe maintenant une classe Event.Handler qui permet de créer des Handlers sur des événements ex:
Vous allez me dire "ben comme avant" ... pas exactement car au lieu de nous renvoyer l'element comme le fait la méthode observe, la méthode on nous renvoie un objet Event.Handler. L'intéret est de faciliter l'arret du handler: avant, pour stopper l'observation d'un element, il fallait que observe et stopObserving prennent la même fonction en parametre. Adieu fonction anonyme, on était donc obligé de variabiliser la fonction pour pouvoir l'arrêter:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 var elem = $("unElement"); var handler = elem.on("click", function(e) { alert(element.element().identify() + " a été cliqué"); })
maintenant, on obtient avec on un Event.Handler que l'on peut stopper, redémarrer à souhait:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 var elem = $("unElement"); var clickObserver = function(e) { alert(e.element().identify() + " a été cliqué"); } elem.observe("click", clickObserver); // .. plein de code trop bien elem.stopObserving("click", clickObserver);
Une autre subtilité vien du fait que désormais, entre le nom de l'événement et le callback, on peut ajouter un selector css. Lors de l'appel au callback, en plus de l'événement un objet est passé. Il correspond au premier ancetre de l'initiateur de l'evenement qui vérifie la contrainte du selecteur. Si rien ne correspond, la doc dit que c'est l'element qui observe qui est passé, mais moi je n'ai plus d'événement. Peut-être que j'ai mal compris, en tout cas c'est sur que c'est une RC...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 var elem = $("unElement"); var clickHandler = elem.on("click", function(e) { alert(e.element().identify() + " a été cliqué"); }); // .. plein de code trop bien clickHandler.stop(); // ... encore plus dément clickHandler.start();
Enfin, Event.Handler doit pouvoir être créé indépendamment :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 var elem = $("unElement"); var clickHandler = elem.on("click", ".parent", function(e, element) { alert(e.element().identify() + " a été cliqué, " + element.identify() + " est passé en parametre aussi !"); });
Mais encore une fois l'effet démo je dois être incapable de faire fonctionner correctement les outils à ma disposition... ou bien ... c'est la RC
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 var handler = new Event.Handler(elem, "click", function() {alert(e.element().identify() + " a été clické")}); handler.start();
Partager