CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[jQuery] plugin, méthodes...

Pseudo supprimé
Pseudo supprimé 27 mai 2014 à 06:55:50

Salut les loulous,

Je développe régulièrement quelques plugins pour mes besoins (même si d'autres existent déjà), et je cherche à rendre ça le plus propre et le plus optimisé possible.

J'ai donc quelques questions, basons-nous sur ce plugin-ci : https://github.com/RhooManu/jQuery-ScrollOffset/blob/master/jquery.scrolloffset.js

En l'état, tout est englobé dans la fonction .fn : Chaque action, les paramètres par défaut... D'où ma question : Même si dans ce cas précis je n'ai pas de fonctions/méthodes particulière, est-ce plus pertinent de placer les éléments de façon séparée (par exemple, avoir un $.scrollOffset.prototype = { constructor: $.scrollOffset, [...] }; pour déclarer méthodes et constructeur) et au final simplement appeler le constructeur dans la fonction .fn (via un :
$.fn.scrollOffset= function(options){
if (this.length === 1) {
current = new $.scrollOffset(this, options);
}
return this;
};

L'utilité de cette façon de procéder, c'est bien de définir des méthodes pour l'utilisateur ? Il y a d'autres choses à savoir là-dessus (performances éventuellement améliorée, meilleure réutilisabilité...) ?
Est-ce applicable à tout type de "projet", ou bien est-ce que ça n'est pertinent qu'à partir d'un certain niveau de complexité (et à ce moment là, comment savoir si ça devient nécessaire ou point) ?

Merci :)

Pseudo supprimé
Pseudo supprimé 27 mai 2014 à 08:01:22

J'ai réussi à développer une version fonctionnelle du plugin d'exemple, avec cette seconde façon de faire.

Donc, pour faciliter la question, qu'est-ce qu'il vaut mieux faire (et pourquoi) ?
Ça : https://github.com/RhooManu/jQuery-ScrollOffset/blob/master/jquery.scrolloffset.js
Ou ça : https://github.com/RhooManu/jQuery-ScrollOffset/blob/develop/jquery.scrolloffset.js

Merci :)

vava740
vava740
Niveau 10
27 mai 2014 à 08:34:46

J'ai pas regardé attentivement le code, mais ce que je vois, c'est que le premier est plus court et particulièrement simple à lire sans se prendre la tête. Le deuxième est plus long et plus compliqué, tu amènes le prototype dans le jeu alors que tu ne sembles pas en avoir besoin.

Après avoir regardé un peu plus attentivement la 2e version (ce qui n'a pas été nécessaire pour comprendre le 1er code), je vois que ça fait bien la même chose, mais au début j'ai cru voir de loin un singleton (alors que la variable `current` est juste... pas utilisée), qui écraserait la "sélection" précédente à chaque appel de `$().scrollOffset`.

En terme de performance, j'ai pas benchmarké ton code précis, mais j'avais il y a un certain temps comparé un code fonctionnel et un code objet avec prototype (les deux faisaient la même chose, et y'avait des événements). Pour la gestion d'événements en gardant le contexte (sans passer directement par une closure), j'avais été obligé de me faire un helper qui utilise... une closure parce que `Function.prototype.bind` ralentissait clairement l'exécution. Au final la solution la plus rapide a été de faire un gestionnaire d'événements maison qui m'obligeait à passer le `this` à chaque fois que je posais un écouteur d'événements. Je crois que ça égalait quasiment la performance... d'une closure imbriquée. :pf:

Bref je pensais à la base que c'était catastrophique d'imbriquer des closures comme ça (parce que "ça créé une nouvelle fonction à chaque appel"), et j'ai essayé d'"aplatir" mon code en utilisant essantiellement de l'objet par prototype, pas une seule fonction imbriquée, et au final, en plus d'avoir du code moins lisible, c'était aussi plus lent.

Après ça je me suis rendu compte que le JS brillait par son côté fonctionnel, et j'ai presque complètement arrêté de toucher au prototype.

Du coup ce que je peux te conseiller pour améliorer ton _premier_ code, c'est... déjà d'indenter avec 2 espaces :noel: , et si tu veux pas imbriquer trop de fonctions, tu peux donner un nom à la fonction que tu passes à `this.each`, et la remonter tout en haut de ta closure principale (mais ça segmente le code et comme le plugin est encore relativement léger, tu perdras surtout en lisibilité).

Ah et aussi, mettre _toujours_ un espace après le mot clé `function` (donc une fonction anonyme, y'a l'espace, puis... rien, donc la parenthèse ouvrante), mais là c'est le maniaque qui parle. :hap:

Pseudo supprimé
Pseudo supprimé 27 mai 2014 à 08:57:59

Merci pour ton retour !

Effectivement, current est assez inutile en soit ; cela étant, je n'arrive pas à appeler la méthode scroll si ce n'est pas avec current... Je manque quelque chose dans la logique du truc. Si j'utilise element, ça ne fait juste rien, ça n'appelle pas la fonction ; par contre, si j'utilise this.scroll(), j'ai une erreur undefined. De quelle façon appeler scroll ?

Sinon effectivement, ma première réflexion était de me dire que c'était clairement plus chiant à lire et comprendre (preuve en est que j'ai pas encore bien compris la logique du truc moi-même...).

Du coup, tu parles de besoin à propos de prototype... Dans quel cas est-ce que je pourrais en avoir le besoin, justement ?

vava740
vava740
Niveau 10
27 mai 2014 à 12:01:08

Je viens de relire ta fonction, et en fait ma première impression était (quasiment) bonne ("qui écraserait la "sélection" précédente à chaque appel de `$().scrollOffset`").

À chaque appel de `$().scrollOffset`, tu stocke dans `current` la dernière instance du constructeur `scrollOffset`.

Lors d'un clic, tu appelles la méthode `scroll` de ce dernier objet (même si c'est l'écouteur de clic d'un objet précédent). C'est un "moindre mal" comme tu passes la cible en paramètre, ça scrollera au bon endroit, mais le `this` à l'intérieur de `scroll` sera toujours la dernière instance (et par conséquent `this.params` aussi).

Si tu stockais l'élément cible dans une propriété de ton objet (plutôt que de le passer à tes méthodes), tu te serais rendu compte que ça scrollerait systématiquement vers la cible du dernier objet instancié.

La raison pour laquelle tu ne peux pas juste faire `this.scroll()` dans l'événement, c'est que tu es dans une closure qui a son propre `this` (qui est dans ton cas l'élément cible de l'évémement, mais c'est pas ton instance de `scrollOffset`). Tu as plusieurs solutions pour propager le contexte dans une closure (j'y reviens après).

J'ai repris ton code avec pas mal d'annotations pour décrire les changements que j'ai faits, je te propose 3 méthodes pour propager le contexte dans ton événement, et quelques autres améliorations/conventions.

https://wall.deblan.org/x1b03/javascript/1/

Je ne sais pas si ce code est fonctionnel (pas testé), mais je m'en sert surtout comme support pour mes explications en commentaire.

Pseudo supprimé
Pseudo supprimé 27 mai 2014 à 15:29:54

Un gros merci à toi.

Je vois un peu mieux le problème, oui. Je pense que la première méthode est la plus pérenne.

Merci encore de ton aide. :)

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment