Получение массива всех возможных событий DOM - PullRequest
8 голосов
/ 21 февраля 2012

Я создал многоцелевую фабричную функцию генератора событий. С его помощью я могу превратить объекты в источники событий. Код для фабрики генератора событий приведен ниже, если кто-то хочет посмотреть или использовать его.

Мой вопрос: как мне получить список событий из DOM? Обратите внимание, что я не пытаюсь получить список связанных событий. Я хочу получить список всех возможных событий. Я хочу добавить метод "pipe" для эмиттеров. Этот метод будет брать объект DOM и связываться со всеми возможными событиями, а затем, когда любое из этих событий срабатывает, каждое из них вызывает событие с тем же именем в эмиттере.

Я не думаю, что есть способ сделать это. Я готов сделать жестко запрограммированный массив имен событий, но если бы я мог вместо этого получить массив для DOM, это было бы намного лучше и работало бы, если бы W3C стандартизировал больше типов событий.

P.S. Если вы работаете на W3C, это та чушь, которая заставляет всех ненавидеть DOM. Пожалуйста, перестаньте относиться к JavaScript как к игрушечному языку. Это не игрушечный язык и требует больше, чем ваш игрушечный DOM.

/**
 * Creates a event emitter
 */
function EventEmitter() {
    var api, callbacks;

    //vars
    api = {
        "on": on,
        "trigger": trigger
    };
    callbacks = {};

    //return the api
    return api;

    /**
     * Binds functions to events
     * @param event
     * @param callback
     */
    function on(event, callback) {
        var api;

        if(typeof event !== 'string') { throw new Error('Cannot bind to event emitter. The passed event is not a string.'); }
        if(typeof callback !== 'function') { throw new Error('Cannot bind to event emitter. The passed callback is not a function.'); }

        //return the api
        api = {
            "clear": clear
        };

        //create the event namespace if it doesn't exist
        if(!callbacks[event]) { callbacks[event] = []; }

        //save the callback
        callbacks[event].push(callback);

        //return the api
        return api;

        function clear() {
            var i;
            if(callbacks[event]) {
                i = callbacks[event].indexOf(callback);
                callbacks[event].splice(i, 1);

                if(callbacks[event].length < 1) {
                    delete callbacks[event];
                }

                return true;
            }
            return false;
        }
    }

    /**
     * Triggers a given event and optionally passes its handlers all additional parameters
     * @param event
     */
    function trigger(event    ) {
        var args;

        if(typeof event !== 'string' && !Array.isArray(event)) { throw new Error('Cannot bind to event emitter. The passed event is not a string or an array.'); }

        //get the arguments
        args = Array.prototype.slice.apply(arguments).splice(1);

        //handle event arrays
        if(Array.isArray(event)) {

            //for each event in the event array self invoke passing the arguments array
            event.forEach(function(event) {

                //add the event name to the begining of the arguments array
                args.unshift(event);

                //trigger the event
                trigger.apply(this, args);

                //shift off the event name
                args.shift();

            });

            return;
        }

        //if the event has callbacks then execute them
        if(callbacks[event]) {

            //fire the callbacks
            callbacks[event].forEach(function(callback) { callback.apply(this, args); });
        }
    }
}

Ответы [ 3 ]

6 голосов
/ 12 сентября 2013

Вот версия, которая работает в Chrome, Safari и FF.

Object.getOwnPropertyNames(document).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(Object.getPrototypeOf(document)))).filter(function(i){return !i.indexOf('on')&&(document[i]==null||typeof document[i]=='function');})

UPD :

А вот версиякоторый работает в IE9 +, Chrome, Safari и FF.

Object.getOwnPropertyNames(document).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(Object.getPrototypeOf(document)))).concat(Object.getOwnPropertyNames(Object.getPrototypeOf(window))).filter(function(i){return !i.indexOf('on')&&(document[i]==null||typeof document[i]=='function');}).filter(function(elem, pos, self){return self.indexOf(elem) == pos;})

PS: результатом является массив имен событий, например ["onwebkitpointerlockerror", "onwebkitpointerlockchange", "onwebkitfullscreenerror", "onwebkitfullscreenchange", "onselectionchange", "onselectstart", "onsearch", "onreset", "onpaste", "onbeforepaste", "oncopy"] ... ect.

5 голосов
/ 21 февраля 2012

Все события DOM начинаются с on.Вы можете просмотреть любой экземпляр Element и перечислить все свойства, которые начинаются с on.

Пример.Скопируйте и вставьте следующий код в консоль (Firefox, используя Array-понимание;)):

[i for(i in document)].filter(function(i){return i.substring(0,2)=='on'&&(document[i]==null||typeof document[i]=='function');})

Еще один способ получить события - посмотреть спецификацию , которая показывает:

  // event handler IDL attributes
  [TreatNonCallableAsNull] attribute Function? onabort;
  [TreatNonCallableAsNull] attribute Function? onblur;
  [TreatNonCallableAsNull] attribute Function? oncanplay;
  [TreatNonCallableAsNull] attribute Function? oncanplaythrough;
  [TreatNonCallableAsNull] attribute Function? onchange;
  [TreatNonCallableAsNull] attribute Function? onclick;
  [TreatNonCallableAsNull] attribute Function? oncontextmenu;
  [TreatNonCallableAsNull] attribute Function? oncuechange;
  [TreatNonCallableAsNull] attribute Function? ondblclick;
  [TreatNonCallableAsNull] attribute Function? ondrag;
  [TreatNonCallableAsNull] attribute Function? ondragend;
  [TreatNonCallableAsNull] attribute Function? ondragenter;
  [TreatNonCallableAsNull] attribute Function? ondragleave;
  [TreatNonCallableAsNull] attribute Function? ondragover;
  [TreatNonCallableAsNull] attribute Function? ondragstart;
  [TreatNonCallableAsNull] attribute Function? ondrop;
  [TreatNonCallableAsNull] attribute Function? ondurationchange;
  [TreatNonCallableAsNull] attribute Function? onemptied;
  [TreatNonCallableAsNull] attribute Function? onended;
  [TreatNonCallableAsNull] attribute Function? onerror;
  [TreatNonCallableAsNull] attribute Function? onfocus;
  [TreatNonCallableAsNull] attribute Function? oninput;
  [TreatNonCallableAsNull] attribute Function? oninvalid;
  [TreatNonCallableAsNull] attribute Function? onkeydown;
  [TreatNonCallableAsNull] attribute Function? onkeypress;
  [TreatNonCallableAsNull] attribute Function? onkeyup;
  [TreatNonCallableAsNull] attribute Function? onload;
  [TreatNonCallableAsNull] attribute Function? onloadeddata;
  [TreatNonCallableAsNull] attribute Function? onloadedmetadata;
  [TreatNonCallableAsNull] attribute Function? onloadstart;
  [TreatNonCallableAsNull] attribute Function? onmousedown;
  [TreatNonCallableAsNull] attribute Function? onmousemove;
  [TreatNonCallableAsNull] attribute Function? onmouseout;
  [TreatNonCallableAsNull] attribute Function? onmouseover;
  [TreatNonCallableAsNull] attribute Function? onmouseup;
  [TreatNonCallableAsNull] attribute Function? onmousewheel;
  [TreatNonCallableAsNull] attribute Function? onpause;
  [TreatNonCallableAsNull] attribute Function? onplay;
  [TreatNonCallableAsNull] attribute Function? onplaying;
  [TreatNonCallableAsNull] attribute Function? onprogress;
  [TreatNonCallableAsNull] attribute Function? onratechange;
  [TreatNonCallableAsNull] attribute Function? onreset;
  [TreatNonCallableAsNull] attribute Function? onscroll;
  [TreatNonCallableAsNull] attribute Function? onseeked;
  [TreatNonCallableAsNull] attribute Function? onseeking;
  [TreatNonCallableAsNull] attribute Function? onselect;
  [TreatNonCallableAsNull] attribute Function? onshow;
  [TreatNonCallableAsNull] attribute Function? onstalled;
  [TreatNonCallableAsNull] attribute Function? onsubmit;
  [TreatNonCallableAsNull] attribute Function? onsuspend;
  [TreatNonCallableAsNull] attribute Function? ontimeupdate;
  [TreatNonCallableAsNull] attribute Function? onvolumechange;
  [TreatNonCallableAsNull] attribute Function? onwaiting;

  // special event handler IDL attributes that only apply to Document objects
  [TreatNonCallableAsNull,LenientThis] attribute Function? onreadystatechange;
0 голосов
/ 22 февраля 2012

Я прочитал спецификацию и подтвердил, что в настоящее время это невозможно.Спасибо W3C за то, что он не предоставил нам самую основную среду!

Мне удалось обойти эту проблему, не жертвуя при этом ничем.Как я уже говорил, канал передает любые события от другого источника (например, узла DOM) в текущий источник.Однако мне не нужно ничего делать, пока кто-то не попытается прослушать событие.Внутренне то, что я делаю, это привязка к канальным источникам, так как люди привязываются к текущему источнику.

Я выпустил библиотеку , если вам интересно посмотреть, что я сделал.Код для канала находится в методе pipe() и методе on().

...