web-dev-qa-db-fra.com

Écouteur d'événements personnalisé JavaScript

Je me demandais si quelqu'un pouvait m'aider à comprendre exactement comment créer différents écouteurs d'événements personnalisés.

Je n'ai pas de cas spécifique d'un événement mais je veux apprendre en général comment cela se fait, donc je peux l'appliquer là où c'est nécessaire.

Ce que je cherchais à faire, au cas où certaines personnes pourraient avoir besoin de savoir, était:

var position = 0;

for(var i = 0; i < 10; i++)
{
    position++;
    if((position + 1) % 4 == 0)
    {
        // do some functions
    }
}
41
Lpc_dark
var evt = document.createEvent("Event");
evt.initEvent("myEvent",true,true);

// custom param
evt.foo = "bar";

//register
document.addEventListener("myEvent",myEventHandler,false);

//invoke
document.dispatchEvent(evt);

Voici la façon de le faire plus localement, en identifiant les auditeurs et les éditeurs: http://www.kaizou.org/2010/03/generating-custom-javascript-events/

59
Max

L'implémentation d'événements personnalisés n'est pas difficile. Vous pouvez l'implémenter de plusieurs façons. Dernièrement, je le fais comme ceci:

/***************************************************************
*
*   Observable
*
***************************************************************/
var Observable;
(Observable = function() {
}).prototype = {
    listen: function(type, method, scope, context) {
        var listeners, handlers;
        if (!(listeners = this.listeners)) {
            listeners = this.listeners = {};
        }
        if (!(handlers = listeners[type])){
            handlers = listeners[type] = [];
        }
        scope = (scope ? scope : window);
        handlers.Push({
            method: method,
            scope: scope,
            context: (context ? context : scope)
        });
    },
    fireEvent: function(type, data, context) {
        var listeners, handlers, i, n, handler, scope;
        if (!(listeners = this.listeners)) {
            return;
        }
        if (!(handlers = listeners[type])){
            return;
        }
        for (i = 0, n = handlers.length; i < n; i++){
            handler = handlers[i];
            if (typeof(context)!=="undefined" && context !== handler.context) continue;
            if (handler.method.call(
                handler.scope, this, type, data
            )===false) {
                return false;
            }
        }
        return true;
    }
};

L'objet Observable peut être réutilisé et appliqué par n'importe quel constructeur en ayant besoin simplement en mélangeant le prototype d'Observable avec le prototype de ce constructeur.

Pour commencer à écouter, vous devez vous inscrire à l'objet observable, comme ceci:

var obs = new Observable();
obs.listen("myEvent", function(observable, eventType, data){
    //handle myEvent
});

Ou si votre écouteur est une méthode d'un objet, comme ceci:

obs.listen("myEvent", listener.handler, listener);

Où écouteur est une instance d'un objet, qui implémente la méthode "handler".

L'objet Observable peut désormais appeler sa méthode fireEvent chaque fois qu'il se passe quelque chose qu'il souhaite communiquer à ses écouteurs:

this.fireEvent("myEvent", data);

Où les données sont des données que les auditeurs peuvent trouver intéressantes. Tout ce que vous y mettez dépend de vous - vous savez mieux en quoi consiste votre événement personnalisé.

La méthode fireEvent passe simplement par tous les écouteurs qui ont été enregistrés pour "myEvent" et appelle la fonction enregistrée. Si la fonction retourne false, cela signifie que l'événement est annulé et l'observable n'appellera pas les autres écouteurs. En conséquence, toute la méthode fireEvent retournera également à la vitesse de sorte que l'observable sache que quelle que soit l'action dont il avertissait ses auditeurs, elle doit maintenant être annulée.

Peut-être que cette solution ne convient pas à tout le monde, mais j'ai beaucoup profité de ce morceau de code relativement simple.

42
Roland Bouman

D'ici:

https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

// create the event
var evt = document.createEvent('Event');
// define that the event name is `build`
evt.initEvent('build', true, true);

// elem is any element
elem.dispatchEvent(evt);


// later on.. binding to that event
// we'll bind to the document for the event delegation style. 
document.addEventListener('build', function(e){
   // e.target matches the elem from above
}, false);
9
newshorts

Voici une implémentation vraiment simple (TypeScript/Babelish):

const simpleEvent = <T extends Function>(context = null) => {
    let cbs: T[] = [];
    return {
        addListener: (cb: T) => { cbs.Push(cb); },
        removeListener: (cb: T) => { let i = cbs.indexOf(cb); cbs.splice(i, Math.max(i, 0)); },
        trigger: (<T> (((...args) => cbs.forEach(cb => cb.apply(context, args))) as any))
    };
};

Vous l'utilisez comme ceci:

let onMyEvent = simpleEvent();
let listener = (test) => { console.log("triggered", test); };
onMyEvent.addListener(listener);
onMyEvent.trigger("hello");
onMyEvent.removeListener(listener);

Ou dans des cours comme celui-ci

class Example {
    public onMyEvent = simpleEvent(this);
}

Si vous voulez du JavaScript simple, vous pouvez le transpiler en utilisant aire de jeux TypeScript .

4
Ciantic