Пользовательский обработчик событий JavaScript - PullRequest
40 голосов
/ 12 марта 2012

Мне было интересно, может ли кто-нибудь помочь мне понять, как именно создавать различные пользовательские прослушиватели событий.

У меня нет конкретного случая события, но я хочу в общих чертах узнать, как это делаетсятак что я могу применить его там, где это необходимо.

То, что я хотел сделать, просто, если некоторые люди, возможно, должны знать, было:

var position = 0;

for(var i = 0; i < 10; i++)
{
    position++;
    if((position + 1) % 4 == 0)
    {
        // do some functions
    }
}

Ответы [ 4 ]

59 голосов
/ 10 апреля 2012
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);

Вот способ сделать это более локально, выявляя слушателей и издателей: http://www.kaizou.org/2010/03/generating-custom-javascript-events/

42 голосов
/ 12 марта 2012

Реализация пользовательских событий не сложно.Вы можете реализовать это многими способами.В последнее время я делаю это так:

/***************************************************************
*
*   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;
    }
};

Объект Observable может быть повторно использован и применен любым конструктором, который ему нужен, просто смешав прототип Observable с прототипом этого конструктора.

Чтобы начать прослушивание, вы должны зарегистрировать себя в наблюдаемом объекте, например:

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

Или, если ваш слушатель является методом объекта, например:

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

Где слушатель является экземпляром объекта, который реализует метод «обработчик».

Объект Observable теперь может вызывать свой метод fireEvent всякий раз, когда происходит что-то, что он хочет сообщить своим слушателям:

this.fireEvent("myEvent", data);

Где данные - это некоторые данные, которые слушатели могут найти интересными.Независимо от того, что вы добавили, это зависит от вас - вы лучше знаете, из чего состоит ваше пользовательское событие.

Метод fireEvent просто проходит через все прослушиватели, которые были зарегистрированы для «myEvent», и вызывает зарегистрированную функцию.,Если функция возвращает false, то это означает, что событие отменено, и наблюдаемое не будет вызывать других слушателей.В результате весь метод fireEvent будет также возвращать fasle, поэтому наблюдаемая знает, что любое действие, о котором она уведомляла своих слушателей, теперь должно быть отменено.

Возможно, это решение подходит не всем, но я имелмного пользы от этого относительно простого куска кода.

9 голосов
/ 28 июня 2012

Отсюда:

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);
4 голосов
/ 30 июня 2016

Вот действительно простая (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))
    };
};

Вы используете это так:

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

Или в таких классах, как это

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

Если вы хотите простой JavaScript, вы можете перенести его, используя TypeScript игровая площадка .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...