Capture all javascript events

Capture all the events (javascript)

Problems include: dynamically added elements, events whose propagation or bubbling is prevented, and custom events that are generated dynamically. There is a strategy called » event delegation «, where you work out the events you need to listen for, then setup listeners as close to the event targets as you can on an element that doesn’t change (e.g. a table element if you are dynamically adding and removing table rows, or a container div for other elements) for the specific event types you need to respond to.

Capture all the events (javascript)

I want to be able to capture all events that are both created and dispatched and fire some callback when that happens.

Also, I would like to be able to fire a callback anytime an event is paired with an event listener.

Problems include: dynamically added elements, events whose propagation or bubbling is prevented, and custom events that are generated dynamically. I imagine there would need to be a prototyping of dispatchEvent or something, but I am unsure. Is this even possible?

  1. Events are dispatched «on» a DOM object (usually an element) that is the event target.
  2. Events can firstly propagate down to child elements in a capture phase. This phase is rarely used since it wasn’t supported by some widely used browsers until recently.
  3. Events can secondly propagate up to parent elements in a bubbling phase. This phase is commonly used.
  4. Some events don’t propagate, they have neither a capture or bubble phase (e.g. focus, blur and submit events). Some events that propagate in some browsers don’t propagate in others.
  5. DOM elements that respond to events have an event handler. It can be set to listen for particular events and call a listener function when that event reaches the element, either during capture, bubbling or if the element is an event target.
  6. Listeners can cancel propagation, e.g. a click event on a span inside a link can cancel propagation so the link doesn’t get the click

Given the above, it is a practical impossibility to «capture all events» using the Events API. It would require establishing a listener for every event type on every element and be impossible to capture custom events because you have to know about them to set an appropriate listener.

I imagine there would need to be a prototyping of dispatchEvent or something

dispatchEvent is a method of an Event instance, it’s not specified to be a constructor (there is no requirement for it to have an internal [[Construct]] method) so not practical to use as such. Browsers aren’t required to implement prototype inheritance for host objects (though most do), and the implementation details of host objects and methods are largely hidden, so this is not an option.

You might try extending the Event API, but you really should not mess with host objects .

It seems that you are concerned about dynamically added elements. There is a strategy called » event delegation «, where you work out the events you need to listen for, then setup listeners as close to the event targets as you can on an element that doesn’t change (e.g. a table element if you are dynamically adding and removing table rows, or a container div for other elements) for the specific event types you need to respond to.

You can also have the functions that are modifying the DOM dispatch custom events to add listeners or whatever.

Читайте также:  Видеокурс по php специалист

If you really want to do this, then you can override addEventListener to keep track of events being registered and fired.

var myEventManager = (function() < var old = EventTarget.prototype.addEventListener, listeners = [], events = []; EventTarget.prototype.addEventListener = function(type, listener) < function new_listener(listener) < return function(e) < events.push(e); // remember event return listener.call(this, e); // call original listener >; > listeners.push([type, listener]); // remember call return old.call(this, type, new_listener(listener)); // call original >; return < get_events: function() < return events; >, get_listeners: function() >; >()); 

However, there are uncountable reasons not to do this, not least the fact that you will quickly run out of memory as you record thousands of events such as mouse moves. This will also not capture event listeners set in ways such as elt.onclick . Nor of course will it catch listeners set up via the old IE attachEvent API. Most importantly, it will not help with you that events that are generated and listened for internally, such as a mouse click on a check box. (A complete solution would also require handling removeEventListener .)

You can also override createEvent and dispatch in similar fashion, but again, that will capture only events that are explicitly created or dispatched in the JS code.

If you really want to do what you seem to be wanting to, I guess you need to fork Chrome.

Jquery — JavaScript catch event, JavaScript catch event. Ask Question Asked 9 years, 5 In this situation, how can I catch just the second div’s click event, and leave the first div. I learnt about the event bubbling, and tunnelling in C# is that the problem. What is about if I want that the parent the first panel does not catch the event, but the …

Is it possible to programmatically catch all events on the page in the browser?

First of all, here is a list of event types that are defined by the W3C standards. (This list is based on the onevent attributes defined in the HTML5 standard. I assume that there are dozens of other event types, but this list is long enough as it is.)

  • abort
  • afterprint
  • beforeprint
  • beforeunload
  • blur
  • canplay
  • canplaythrough
  • change
  • click
  • contextmenu
  • copy
  • cuechange
  • cut
  • dblclick
  • DOMContentLoaded
  • drag
  • dragend
  • dragenter
  • dragleave
  • dragover
  • dragstart
  • drop
  • durationchange
  • emptied
  • ended
  • error
  • focus
  • focusin
  • focusout
  • formchange
  • forminput
  • hashchange
  • input
  • invalid
  • keydown
  • keypress
  • keyup
  • load
  • loadeddata
  • loadedmetadata
  • loadstart
  • message
  • mousedown
  • mouseenter
  • mouseleave
  • mousemove
  • mouseout
  • mouseover
  • mouseup
  • mousewheel
  • offline
  • online
  • pagehide
  • pageshow
  • paste
  • pause
  • play
  • playing
  • popstate
  • progress
  • ratechange
  • readystatechange
  • redo
  • reset
  • resize
  • scroll
  • seeked
  • seeking
  • select
  • show
  • stalled
  • storage
  • submit
  • suspend
  • timeupdate
  • undo
  • unload
  • volumechange
  • waiting

Now, is it possible to define a global event handler that is called when any event originally occurs on any element on the page? (In this case, I don’t want to count those events that occurred on elements because they bubbled up from a descendant element — that’s why I wrote «originally occurs».)

If that is not possible, is it at least possible to define an event handler that is called when any event bubbles up to the root of the DOM tree (which is either the document object or the window object — both should work)? (I know that it’s possible to stop bubbling programmatically, but I would use this event handler on a page that has no other handlers defined on any other elements.) (Also, I believe some events don’t bubble up, but let’s ignore these cases for the sake of this argument.)

Читайте также:  Kotlin бэкэнд или фронтэнд

I know that I can do this (using jQuery):

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

but that would be a rather undesirable solution for me.

btw I don’t need a cross-browser solution. If it works in just one browser, I’m fine.

Also, Firebug is able to log events, but I would like to be able to catch the event programmatically (via JavaScript) rather then having them simply logged in the console.

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

You can iterate through all properties of dom element and select ones that match /on(.*)/ pattern (for example onclick or onmousemove):

var events = []; for (var property in element) < var match = property.match(/^on(.*)/) if (match) < events.push(match[1]); >> console.log(events.join(' ')) 

I highly doubt there’s a way to do this in Firefox. Looking at Firebug’s source code (particularly the attachAllListeners method), turns out that iterating through a list of event names is obviously the way to go, but this doesn’t solve the bubbling issues.

There doesn’t seem to be any ‘easy-way’ to do that.

My idea: You know which are all the events, so you can handle all events for every DOM element:

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()

That’s the ‘intuitive idea’ but doesn’t seem to be very efficient. However, it should work.

Читайте также:  How to remove file in python

How can I trigger a JavaScript event click, The easiest way to do this is through Chrome or Opera (my examples will use Chrome) using the Console. Enter the following code into the console (generally in 1 line): var l = document.getElementById (‘testLink’); for (var i=0; i <5; i++) < l.click (); >This will generate the required result.

JavaScript — Hook in some check on all ‘click’ events

So I have a regular onclick event attached to a few buttons, each function that handles the onclick event does something different (so I can’t reuse the same function for both events).

element1.onclick = function() < if(this.classList.contains('disabled') < return false; >// For example make an AJAX call >; element2.onclick = function() < if(this.classList.contains('disabled') < return false; >// For example hide a div >; 

I’m writing duplicate code for this ‘disabled’ class check, I want to eliminate this by hooking in some common onclick check then fire the regular onclick event if that check passes.

I know the below won’t work but I think it will illustrate what I’m trying to do:

document.addEventListener('click', function() < // 1. Do the disabled check here // 2. If the check passes delegate the event to the proper element it was invoked on // 3. Otherwise kill the event here >); 

I’m not using any JavaScript library and I don’t plan to, in case someone comes up with ‘Just use jQuery’ type answers.

EDIT: Had to pass boolean third argument to addEventListener as true and everything is fine.

Use event capturing, like so:

document.addEventListener('click', function(event) < if (/* your disabled check here */) < // Kill the event event.preventDefault(); event.stopPropagation(); >// Doing nothing in this method lets the event proceed as normal >, true // Enable event capturing! ); 

Sounds like you need to set the capture flag to true and then use .stopPropagation() on the event if a certain condition is met at the target, f.ex:

document.addEventListener('click', function(e) < if ( condition ) < e.stopPropagation(); // do soemthing else, the default onclick will never happen >>, true);​​​​​​​​​​​​​​​​​​​​​​ 

Here is a demo: http://jsfiddle.net/v9TEj/

You can create a generic function that receives a callback:

//check everything here function handleOnclick(callback) < if(this.classList.contains("disabled")) < return false; >else < callback(); //callback here >> //and now on every onclick, just pass the custom behavior element1.onclick = function() < handleOnClick(function() < console.log('element1 onclick fire'); // For example hide a div >); >; element2.onclick = function() < handleOnClick(function() < console.log('element2 onclick fire'); // For example ajax request >); >; 

Edit Based on your latest comment, let me know if this rewrite works for you. only one biding this time.

element1.customFunction = function() < handleOnClick(function() < console.log('element1 onclick fire'); // For example hide a div >); >; element2.customFunction = function() < handleOnClick(function() < console.log('element2 onclick fire'); // For example ajax request >); >; document.addEventListener('click', function() < //1. grab the element //2. check if it has the customFunction defined //3. if it does, call it, the check will be done inside >; 

Javascript — How to catch event when user clicks outside, I click on a button; Ajax call is made to the server; data is returned and modal is shown; Problem: When user clicks on the close button or the «X» in the corner I catch this event by assigning a class to these two elements and assigning an event to this class. Code: $(document).on(«click», «.dialogTankClose», …

Источник

Оцените статью