Можно ли программно отлавливать все события на странице в браузере? - PullRequest
47 голосов
/ 24 февраля 2011

Прежде всего, вот список типов событий, которые определены стандартами W3C. (Этот список основан на атрибутах onevent, определенных в стандарте HTML5. Я предполагаю, что существуют десятки других типов событий, но этот список достаточно длинный.)

  • прервать
  • afterprint
  • BeforePrint
  • beforeunload
  • Размытие
  • canplay
  • canplaythrough
  • изменение
  • нажмите
  • ContextMenu
  • копия
  • cuechange
  • вырезано
  • DblClick
  • DOMContentLoaded
  • сопротивление
  • dragend
  • DragEnter
  • DragLeave
  • DragOver
  • dragstart
  • капля
  • durationchange
  • 1052 * закончился *
  • ошибка
  • внимание
  • focusin
  • focusout
  • formchange
  • forminput
  • hashchange
  • ввод
  • недействительный
  • KeyDown
  • 1074 * нажатие клавиши *
  • KeyUp
  • нагрузки
  • loadeddata
  • loadedmetadata
  • loadstart
  • сообщение
  • MouseDown
  • MouseEnter
  • MouseLeave
  • MouseMove
  • MouseOut
  • 1098 * Mouseover *
  • MouseUp
  • MouseWheel
  • отсутствует
  • онлайн
  • pagehide
  • pageshow
  • паста
  • пауза
  • играть
  • игры
  • popstate
  • прогресс
  • ratechange
  • readystatechange
  • 1128 * повтор * * * Сбросить тысячу сто двадцать девять
  • размер
  • перемотать
  • добившиеся
  • поиск
  • выберите
  • показать
  • застопорился
  • хранение
  • отправить
  • 1150 * приостановить *
  • timeupdate
  • отмена
  • выгрузка
  • volumechange
  • ждет

Теперь, можно ли определить глобальный обработчик событий, который вызывается, когда любое событие первоначально происходит на любом элементе на странице? (В этом случае я не хочу считать те события, которые произошли в элементах, потому что они всплыли из элемента-потомка - поэтому я написал «первоначально происходит».)

Если это невозможно, возможно ли по крайней мере определить обработчик события, который вызывается, когда любое событие всплывает до корня дерева DOM (которое является либо объектом document, либо объект window - оба должны работать)? (Я знаю, что можно прекратить пузыриться программно, но я бы использовал этот обработчик событий на странице, у которой нет других обработчиков, определенных для каких-либо других элементов.) (Кроме того, я считаю, что некоторые события не всплывают, но давайте проигнорируем эти дела ради этого аргумента.)

Я знаю, что могу сделать это (используя jQuery):

$(document).bind('abort afterprint beforeprint beforeunload etc.', function() {
    // handle event
});

но это было бы довольно нежелательным решением для меня.

Кстати, мне не нужно кросс-браузерное решение. Если это работает только в одном браузере, я в порядке.

Кроме того, Firebug может регистрировать события , но я хотел бы иметь возможность отлавливать событие программно (через JavaScript), а не просто регистрировать их в консоли.

Ответы [ 5 ]

20 голосов
/ 11 августа 2015
/*

function getAllEventTypes(){

  if(location.href !='https://developer.mozilla.org/en-US/docs/Web/Events') return;

  var types = {};
  $('.standard-table:eq(0) tr').find('td:eq(1)').map(function(){
    var type = $.trim(this.innerText) || 'OtherEvent';
    types[type] = types[type] || [];     
    var event = $.trim(this.previousElementSibling.innerText);
    if(event) types[type].push(event);
  });
  for(var t in types) types[t] = types[t].join(' ');
  return "var DOMEvents = "+JSON.stringify(types, null, 4).replace(/"(\w+)\":/ig, '$1:');
}

*/

var DOMEvents = {
UIEvent: "abort DOMActivate error load resize scroll select unload",
ProgressEvent: "abort error load loadend loadstart progress progress timeout",
Event: "abort afterprint beforeprint cached canplay canplaythrough change chargingchange chargingtimechange checking close dischargingtimechange DOMContentLoaded downloading durationchange emptied ended ended error error error error fullscreenchange fullscreenerror input invalid languagechange levelchange loadeddata loadedmetadata noupdate obsolete offline online open open orientationchange pause pointerlockchange pointerlockerror play playing ratechange readystatechange reset seeked seeking stalled submit success suspend timeupdate updateready visibilitychange volumechange waiting",
AnimationEvent: "animationend animationiteration animationstart",
AudioProcessingEvent: "audioprocess",
BeforeUnloadEvent: "beforeunload",
TimeEvent: "beginEvent endEvent repeatEvent",
OtherEvent: "blocked complete upgradeneeded versionchange",
FocusEvent: "blur DOMFocusIn  Unimplemented DOMFocusOut  Unimplemented focus focusin focusout",
MouseEvent: "click contextmenu dblclick mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup show",
SensorEvent: "compassneedscalibration Unimplemented userproximity",
OfflineAudioCompletionEvent: "complete",
CompositionEvent: "compositionend compositionstart compositionupdate",
ClipboardEvent: "copy cut paste",
DeviceLightEvent: "devicelight",
DeviceMotionEvent: "devicemotion",
DeviceOrientationEvent: "deviceorientation",
DeviceProximityEvent: "deviceproximity",
MutationNameEvent: "DOMAttributeNameChanged DOMElementNameChanged",
MutationEvent: "DOMAttrModified DOMCharacterDataModified DOMNodeInserted DOMNodeInsertedIntoDocument DOMNodeRemoved DOMNodeRemovedFromDocument DOMSubtreeModified",
DragEvent: "drag dragend dragenter dragleave dragover dragstart drop",
GamepadEvent: "gamepadconnected gamepaddisconnected",
HashChangeEvent: "hashchange",
KeyboardEvent: "keydown keypress keyup",
MessageEvent: "message message message message",
PageTransitionEvent: "pagehide pageshow",
PopStateEvent: "popstate",
StorageEvent: "storage",
SVGEvent: "SVGAbort SVGError SVGLoad SVGResize SVGScroll SVGUnload",
SVGZoomEvent: "SVGZoom",
TouchEvent: "touchcancel touchend touchenter touchleave touchmove touchstart",
TransitionEvent: "transitionend",
WheelEvent: "wheel"
}

var RecentlyLoggedDOMEventTypes = {};

for(DOMEvent in DOMEvents){

  var DOMEventTypes = DOMEvents[DOMEvent].split(' ');

  DOMEventTypes.filter(function(DOMEventType){
    var DOMEventCategory = DOMEvent + ' '+DOMEventType;  
    document.addEventListener(DOMEventType, function(e){
      if(RecentlyLoggedDOMEventTypes[DOMEventCategory]) return;
      RecentlyLoggedDOMEventTypes[DOMEventCategory] = true;
      setTimeout(function(){ RecentlyLoggedDOMEventTypes[DOMEventCategory] = false }, 5000);
      var isActive = e.target==document.activeElement;
      if(isActive) {
        console.info(DOMEventCategory, 
          ' target=', e.target, 
          ' active=', document.activeElement, 
          ' isActive=', true );
      } else {
        console.log(DOMEventCategory, 
          ' target=', e.target,
          ' active=', document.activeElement, 
          ' isActive=', false );
      }

    }, true);
  });

}
8 голосов
/ 18 марта 2015

Вы можете перебрать все свойства элемента dom и выбрать те, которые соответствуют шаблону /on(.*)/ (например, onclick или onmousemove):

var events = [];
for (var property in element) {
    var match = property.match(/^on(.*)/)
    if (match) { 
        events.push(match[1]);
    }
}
console.log(events.join(' '))
5 голосов
/ 27 февраля 2011

Я очень сомневаюсь, что есть способ сделать это в Firefox. Если посмотреть на исходный код Firebug (в частности, на метод attachAllListeners), выясняется, что итерации по списку имен событий - это, безусловно, путь, но это не решает проблемы пузырей.

2 голосов
/ 25 февраля 2011

Кажется, что нет простого способа сделать это.

Моя идея: Вы знаете, какие все события, поэтому вы можете обрабатывать все события для каждого элемента DOM:

var events =
[   
    "onabort",
    "onafterprint",
    "onbeforeprint",
    "onbeforeunload",
    ...

];

var root = document.body;
var elms = root.childNodes;

for(var i = 0; i < elms.length; i++)
{
    for(var j = 0; j < events.length; j++)
    {
        elms[i][events[j]] = globalHandler;
    }
}

function globalHandler()
{
    alert("Global handler called");
}

Это «интуитивная идея», но, похоже, она не очень эффективна. Тем не менее, это должно работать.

Удачи.

0 голосов
/ 28 августа 2017

Для последней версии сайта MDN:

(function getAllEventTypes(){
  if(location.href !='https://developer.mozilla.org/en-US/docs/Web/Events') return;

  var types = {};
  $('.standard-table').map(function(){
    if($(this).find('caption').length > 0){
        var type = $(this).find('caption')[0].innerHTML || 'OtherEvent';
    types[type] = types[type] || [];     
    $(this).find('tbody tr td code a').each(function(el){
        if(this.innerText) types[type].push(this.innerText);
    });
    }
  });
  for(var t in types) types[t] = types[t].join(' ');
  return "var DOMEvents = "+JSON.stringify(types, null, 4).replace(/"(\w+)\":/ig, '$1:');
})();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...