it-swarm.com.de

Ist es möglich, alle Ereignisse auf der Seite im Browser programmgesteuert abzufangen?

Zunächst eine Liste von Ereignistypen, die durch die W3C-Standards definiert sind. (Diese Liste basiert auf den im HTML5-Standard definierten onevent-Attributen. Ich gehe davon aus, dass es Dutzende anderer Ereignistypen gibt, aber diese Liste ist lang genug, wie sie ist.) 

  • abbrechen
  • nachdruck
  • vorabdruck
  • vor dem Entladen
  • verwischen
  • kann spielen
  • durchspielen
  • veränderung
  • klicken
  • kontextmenü
  • kopieren
  • cuechange
  • schnitt
  • dblclick
  • DOMContentLoaded
  • ziehen
  • dragend
  • dragenter
  • dragleave
  • drüber ziehen
  • dragstart
  • drop
  • daueränderung
  • geleert
  • endete
  • error
  • fokus
  • focusin
  • focusout
  • formularänderung
  • formeingabe
  • hashchange
  • eingang
  • ungültig
  • taste nach unten
  • tastendruck
  • keyup
  • belastung
  • loadeddata
  • geladene Metadaten
  • ladestart
  • botschaft
  • maus nach unten
  • mouseenter
  • mouseleave
  • mousemove
  • mouseout
  • mouseover
  • mouseup
  • mausrad
  • offline
  • online
  • seite ausblenden
  • pageshow
  • einfügen
  • pause
  • abspielen
  • spielen
  • popstate
  • fortschritt
  • ratechange
  • readystatechange
  • wiederholen
  • zurücksetzen
  • größe ändern
  • scroll
  • gesucht
  • suchend
  • wählen
  • show
  • ins Stocken geraten
  • lager
  • einreichen
  • aussetzen
  • zeitupdate
  • undo
  • entladen
  • volumenänderung
  • warten

Ist es jetzt möglich, einen globalen Ereignishandler zu definieren, der aufgerufen wird, wenn das Ereignis any ursprünglich auf dem Element any der Seite auftritt? (In diesem Fall möchte ich nicht die Ereignisse zählen, die in Elementen aufgetreten sind, weil sie von einem abgeleiteten Element gesprudelt wurden - deshalb schrieb ich "ursprünglich tritt auf").

Wenn dies nicht möglich ist, ist es zumindest möglich, einen Event-Handler zu definieren, der aufgerufen wird, wenn any -Ereignis bis zum Stamm des DOM-Baums (der entweder das document-Objekt oder das window-Objekt ist) - beide sollten funktionieren ) (Ich weiß, dass es möglich ist, das Blubbern programmatisch zu stoppen, aber ich würde diesen Event-Handler auf einer Seite verwenden, für die keine anderen Handler für andere Elemente definiert sind.) (Außerdem glaube ich, dass einige Ereignisse nicht blubbern, aber ignorieren Sie diese Fälle für dieses Argument.)

Ich weiß, dass ich dies tun kann (mit jQuery): 

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

aber das wäre für mich eine eher unerwünschte Lösung.

Übrigens brauche ich keine Cross-Browser-Lösung. Wenn es nur in einem Browser funktioniert, geht es mir gut.

Firebug kann Ereignisse protokollieren , aber ich möchte das Ereignis programmgesteuert (über JavaScript) abfangen, anstatt es einfach in der Konsole einzuloggen.

45
Šime Vidas
/*

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);
  });

}
17
Vlad Mysla

Sie können alle Eigenschaften des dom-Elements durchlaufen und diejenigen auswählen, die dem Muster /on(.*)/ entsprechen (z. B. onclick oder onmousemove):

var events = [];
for (var property in element) {
    var match = property.match(/^on(.*)/)
    if (match) { 
        events.Push(match[1]);
    }
}
console.log(events.join(' '))
7
YankovskyAndrey

Ich bezweifle sehr, dass dies in Firefox möglich ist. Ein Blick auf den Quellcode von Firebug (insbesondere die attachAllListeners-Methode) zeigt, dass das Durchlaufen einer Liste von Ereignisnamen offensichtlich der beste Weg ist, aber das löst nicht die sprudelnden Probleme.

5

Es scheint keinen "einfachen Weg" dafür zu geben.

Meine Idee: Sie wissen, was alle Ereignisse sind. Sie können also alle Ereignisse für jedes DOM-Element verarbeiten:

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");
}

Das ist die "intuitive Idee", scheint aber nicht sehr effizient zu sein. Es sollte jedoch funktionieren.

Viel Glück.

2
josec89

Ein bisschen zu spät zur Party, aber ich habe etwas geschaffen, das für andere hier nützlich sein könnte.

https://codepen.io/phreaknation/pen/QmJjEa

Dies ist eine ES6-Klasse, die alle Ereignisse eines Elements erfasst, das diesem Element bekannt ist. In dieser Demo können Sie die Elementzeit auf der Seite ändern, die Ereignisse mit anklickbaren Links zu ihrer MDN-Seite auslesen sowie mit dem Element interagieren und sehen, wie die Ereignisse mit Zeitstempeln ausgelöst werden.

Ich hoffe das hilft

Klassencode

class EventSystem {
  constructor(element) {
    this._ = {
      element: null
    }

    return this;
  }

  getAllEventTypes({blacklist = [], whitelist = []} = {}) {
    const events = [];
    for (let property in this._.element) {
      const match = property.match(/^on(.*)/);
      if (match) {
        if ((whitelist.length > 0 ? whitelist.indexOf(match) !== -1 : true) &&
            (blacklist.length > 0 ? blacklist.indexOf(match) === -1 : true)) {
          events.Push(match[1]);
        }          
      }
    }
    return events;
  }

  getElementType() {
    return this._.element.tagName.toLowerCase();
  }

  setElement(element) {
    this._.element = element;
    return this;
  }

  applyEvents(events, callback) {
    events.forEach((event) => {
      this._.element.addEventListener(event, (ev) => {
        if (typeof callback === 'function') {
          callback(event, ev);
        }
      })
    })
  }
}
0
Phreak Nation

Für die letzte Version der MDN-Website:

(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:');
})();
0
Martino Lessio