Un accordeon en JQuery POO

Par reuno92, il y a 9 ans


Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

Je cherche à faire un accordeon en utilisant jQuery et en programmation orienté objet
(POO = voie ô combien compliqué pour le petit scarabée que je suis) :

HTML

<h2 class="section-title">Un titre</h2> <section>...</section> <h2>Un autre titre</h2 <section>...</section>

Jquery

$('document').ready(function(){ var Accordeon = { init : function() { var titre = $('.section-title'); var cache = $(this).next($('section')); titre.on('click', function(){ $(this).disparition(cache); }); }, disparition : function(cible) { if (cible.hasClass('hidden')) { cible.removeClass('bounceInDown'); cible.addClass('bounceInUp'); cible.removeClass('hidden'); } else { cible.removeClass('bounceInUp'); cible.addClass('bounceInDown'); cible.addClass('hidden'); } } }; var accordeon = Object.create(Accordeon); accordeon.init(); });

Ce que je veux

J'aimerais quand je clique sur le h2.section-title fasse disparaître la section frère uniquement avec une classe .hidden { display : none } avec une animation honteusement pompé sur animation.css.

Ce que j'obtiens

Quand je clique sur mon lien h2, dans la console j'obtien un joli " $(...).disparition is not a function ". Je me doute que j'utilise mal le mot-clé this. Mais je ne comprends pas mon erreur...

Je remercie d'avance, à ceux qui pris le temps de lire mon post.

7 réponses

reuno92, il y a 9 ans

Je suis paumé là :p Je crois que je mélange un objet et une classe... En tout cas, merci ça me donne une piste pour améliorer la conception de mon code.

betaWeb, il y a 9 ans

C'est normal, c'est un peu chiant à comprendre au début ;)

betaWeb, il y a 9 ans

Beh oui, tu n'as pas besoin de faire comme ça ! Un Objet JS n'est pas censé être instanciable.

// Objet var monObj = { init: function () { // init } // Code }; monObj.init(); // Class var MaClasse = function (prop) { this.prop = prop; this.init(); // par exemple }; MaClasse.prototype.init = function () { // ton initialisation ici }; MaClasse.prototype.demo = function () { alert(this.prop); }; var maClasse = new MaClasse('Salut la planète'); maClasse.demo(); // alert 'Salut la planète'
betaWeb, il y a 9 ans

Salut,

C'est tout simplement un problème et de contexte et de compréhension. Ensuite, tu ne peux pas instancier un objet jQuery depuis un objet JS.

$('document').ready(function(){ var Accordeon = { init : function() { var self = this; var titre = $('.section-title'); titre.on('click', function () { self.disparition($(this).next($('section'))); }); }, disparition : function(cible) { if (cible.hasClass('hidden')) { cible.removeClass('bounceInDown'); cible.addClass('bounceInUp'); cible.removeClass('hidden'); } else { cible.removeClass('bounceInUp'); cible.addClass('bounceInDown'); cible.addClass('hidden'); } } }; Accordeon.init(); });

Ah et ce que tu as fait j'ai pas du tout du "jQuery POO", d'ailleurs jQuery n'est pas un langage mais une libraire, c'est de JS POO dont il est question.

reuno92, il y a 9 ans

Merci de vos réponses à tout les deux, je résume ce que j'ai compris.

Dans mon code, le contexte c'est :
this = qui va me permettre de naviguer dans mon objet javascript.
$(this) = qui va me permettre de naviguer dans le DOM.

Je pose mon code final pour montrer ce que ça m'a permis de faire (et si ça peut aider quelqu'un :p) :

$('document').ready(function(){ var Accordeon = { init : function() { var self = this; var titre = $('.section-title'); titre.each(function(){ console.log($(this)); $(this).on('click', function(){ self.disparition($(this)); }); }); }, disparition : function(e) { var cache = e.next(); if (cache.hasClass('hidden')) { cache.removeClass('hidden'); } else { cache.addClass('hidden'); } } }; var accordeon = Object.create(Accordeon); accordeon.init(); });

pas facile de jouer à Houdini avec Javascript et jQuery en même temps ^^.

betaWeb, il y a 9 ans

C'est déjà mieux, mais pourquoi tu met un var accordeon = Object.create(Accordeon); ??

reuno92, il y a 9 ans

Tout bêtement j'ai appris comme ça.
Quand je crée une objet :

var Objet = {...}

Fallait toujours l'instancier pour le faire l'exécuter

var monObjet = Object.create(Objet);

Pour pouvoir lancer par la suite mon constructeur

monObjet.init();

Et pour le coup lancer mon script. Y a t'il plus simple ?

En écrivant, ce reply, je me recompte qu'utilisé l'objet n'a peu d'utilité en l'état... Peut être que je devrais changer la propriété titre :

$(document).ready(function() { ... titre : this.titre ... }); var accordeon = Object.create(Accordeon); accordeon.init(titre : $('section-title');

Et pour le coup, dans mon doc si j'ai besoin de faire la même chose avec des h3 ou h4. j'ai peut être pas besoin de recommencer tout le script.