Bonjour,

J'ai un petit système de portfolio. Je suis entraine d'écrire un petit sytème d'événement que l'utilisateur peut écouter, et faire ça propore logique une foit que le plugin est bien chargéVoila je rencontre un petit problème avec mon code.

Ce que je fais

De lancer des événement onShowing, onClick quand un élément s'affiche ou on clique sur un élément

let portfolio =new PortfolioFlex('#js-portfolio-flex');
    portfolio.on('onShowing', function (selector) {
        console.log('Do something when it is displayed')
    })
    portfolio.on('onClick', function (selector) {
        console.log('Do something when it is clicked')
    })

Dans le contructeur de mon plugin je défini une liste d'événement que le utilisateur puisse écouter :

constructor(selector) {
// ....
this.defaultEvents = {
            "onShowing" : (selector) => {},
            "onClick": (selector) => {}
        }
}
// ....

J'ai fait la function on() qui permet d'écouter sur un événment et lancer sa logique :

/**
     *
     * @param eventName
     * @param callback
     */
    on(eventName, callback)  {
        if (!this.isInEventList(eventName)) {
           throw new Error(`The event ${eventName} is not exist`)
        }
        callback(this)
    }

J'ai une fonction qui vérifie si le nom de l'événement existe bien dans l'objet des événement par defaut du plugin. Si non il envoi une exception.

/**
     *
     * @param {string} eventName
     * @return {boolean}
     */
    isInEventList(eventName) {
        return this.defaultEvents[eventName] !== undefined;
    }

Ce que je veux

Dans ma fonction show il déclenche l'événment this.defaultEvents['onShowing']. Par exemple seule la function show lance l'événement onShowing

show(child) {
        let offset = 0;
        if (this.activeContent !== null) {
            this.slideUp(this.activeContent)
            if (this.activeContent.offsetTop < child.offsetTop) {
                offset = this.activeContent.offsetHeight
            }
        }
        if (this.activeItem === child) {
            this.activeContent = null;
            this.activeItem = null
        } else {
            let content = child.querySelector('.js-portfolio-body').cloneNode(true);
            this.injectContent(child, content);
            this.slideDown(content)
            this.scrollTo(child, offset);
            this.activeContent = content;
            this.activeItem = child
        }
        // On execute le code de l'événement **onShowing**
    }

Même chose quand je clique sur un élément du portfolio juste l'événement onClick est lancé

this.children.forEach((child) => {
            child.addEventListener('keypress', (e) => {
                if(e.keyCode === 13) {
                    this.show(child)
                }
            })
            child.addEventListener('click', (e) => {
                e.preventDefault();
                this.show(child)
                // On lance l'événenement onClick
            });

        })

Ce que j'obtiens

Tout les événements de mon objet javascript defaultEvents: {} sont lancé. Comment je peut dire à mon code non tu lance l'événment en question si seulement une action comme show() ou un addEventListner() est lancé.

Merci

1 réponse


Il faut faire les choses en 2 temps:

  • Dans on tu dois "enregistrer" l'évènement (dans un tableau ou objet par exemple) mais tu ne dois pas lancer le callback
  • Dans ton show ou autre tu lancera une méthode trigger('onShowing') qui cherchera tous les callbacks correspondant à onShowing et les lancera.

Dans ton code tu as mélangé la partie trigger / on