I'm trying to debug a web page that makes heavy use of events, and so I need to monitor all events that are fired.
Most of the events are bound using jQuery. Hence, it would be particularly useful if there was a way to specifically monitor only those events.
Of course you can do just fine with Firebug, the console and the scripts tab where you can add breakpoints and watches, but you want to do it smarter / easier obviously.
There is a neat Firebug plugin called EventBug that just logs all the events and groups them by event type so you can expand and see what triggered them.
EventBug doesn't do it realtime, you have to refresh though.
One other way is to use the 'Log Events' feature against any DOM element in Firebug. This does do it realtime and you can see what order events are fired / triggered as well.
Try this:
Toggle open Firebug
Right click the element in HTML tab, if you want to see all events then right click <body>
Choose Log Events from the context menu
Make sure the Console tab is enabled
Click to enable the 'Persist' mode in the Console tab (otherwise Console tab will clear after the page is reloaded)
You may have to select Closed (manually)
Voila! watch events stream in the console tab
This is what you see with Log Events:
Also worth trying the FireQuery add-on for Firebug to see what elements in the DOM have jQuery events attached to them and what they are.
And as benvie's answer mentions, this is possible in webkit's developer tools as well.
This has been introduced some versions ago but as of Firefox 35 events associated with an element can be seen on the Inspector: next to the element which you want to see the events (in case there is any) there will be an icon with the 'EV' letters. Click it and you will see a small popup window with the events for that element.
More info: http://flailingmonkey.com/view-dom-events-in-firefox-developer-tools/
This doesnt exist in Firebug I believe, and the underlying problem is lack of support or lack of exposure at the api level. Alternatively, there's only a few ways to subscribe to DOM events: Element.prototype.addEventListener (and window.addEventListener and document.addEventListener and XMLHttpRequest.addEventListener and some others) aside from 'onevent' properties which are observable and interceptable.
But realistically, the WebKit debugger and Chromium's debugger (which is webkit's with extra points) allow one to debug and observe attached listeners. Sometimes it's easier to debug one browsers's bugs in another browser with better exposure of application/runtime state, even when that browser doesn't exhibit the bug.
https://developers.google.com/chrome-developer-tools/docs/elements
Event Listener Breakpoints have been introduced in FF 69 (and further improved in FF 71). Relevant docs are here.
It allows you to automatically break on any event of a given type. This screenshot (from above article) shows how it breaked on a Keyboard event:
The article further explains (1) how instead of breaking every time, it can just log matching events, and (2) how you can blackbox certain sources, to avoid having to wade through the internals of framework code (such as jquery, react etc.).
They present another screenshot of how that looks like:
Related
I'm debugging some 3rd-party minified Javascript that somewhere is triggering a browser page refresh. However, I can't figure out what part of the code is causing the refresh.
Is there a way to put a breakpoint in Chrome that will be hit just before a page refresh so I can inspect the call stack to see what caused it?
Try this:
Open your Chrome Dev Tools
Navigate to the "Sources" tab
On the right panel, expand "Event Listener Breakpoints"
Expand the "Load" tree
Check the beforeunload and unload options
See if that helps; screenshot below.
Edit: Alternately, if that doesn't work, you can use Chrome to search all loaded scripts for the code that might be responsible. There's apparently a lot of ways to refresh the page with JavaScript but they mostly have a few common strings like "navigator", "location", "reload", "window".
Finally, if there's a link to the same page you are on, it's possible some JS is triggering a click on it-- unlikely, but worth exploring if nothing else has worked thus far...
(Please excuse the formatting as I'm on mobile...)
NOTE: It seems occasionally, for reasons I don't yet fully understand, this solution fails to actually cause the debugger to pause; in this situation, I found that thorǹˆ's answer to this question did the trick for me.
In Firefox (not Chrome, it's important; UPD 2020: it now works in Chrome as well) Developer Tools, go to the console, enter addEventListener('beforeunload',()=>{debugger}), and execute your code. After the debugger stops at the debugger statement, look at the call stack. You'll see what triggered the event. Chrome didn't have it there.
At least, this worked for me.
In the devtool, network pane, toggle the "Preserve log", carefully check the initiator column.
You don't specify what's the 3rd party library does.
If it is a ui component like an ad or something similar, just place it inside an iframe with the sandbox attribute configured as you need.https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe (Scroll down to the sandbox attribute section)
If it is something triggered by an event, just use (in chrome dev tools only) the getEveneListener() function and follow the listener trail... (hard, but possible)
Example:
The listener property will lead you to the actual functions that will be invoked. You can than search them in the obfuscated code and add debugger to understand it's purpose.
There are many other scenarios - if you can specify more.
I am trying to debug a third-party HTML/Javascript page but I can't easily locate the script entry points to set breakpoints on them.
I want the debugger to break on any element's onclick event handler. At the moment if the page is set up with something like
document.getElementById("foo").onclick = bar;
then in general it isn't easy to determine that foo and bar are connected.
So, I want to break on all onclicks, wherever they may be.
Can I do this in Chrome or Firefox?
Chrome:
Chrome inspector -> sources -> Event Listener Breakpoints
Firefox:
get EventBug
You can read a bit more about eventBug in here: Using Firefox, how can I monitor all JavaScript events that are fired?
I am debugging 12K lines of JavaScript. Of course it is written by the off shore team. Now, I need to find out which js function is invoked when I interact with the UI. Is there anyway for me to just automatically jump into the function which is being executed?
I cannot really put a break point since I have no idea where to put the break point?
App runs only on IE7!
You can attach VS 2008 to a scripting host process like Internet Explorer. Notice that "scripting host" is specific to the Windows Scripting platform, which isn't used by other browsers.
Internet Explorer should be configured to "Allow script debugging" so that VS can attach to iexplorer.exe and be able to debug scripts running in it.
Bear in mind that this is an extremely frustrating debugging experience. If you can debug in more modern browsers (including IE9, which has decent developer tools), please do so!
Once you've attached Visual Studio to IE7, you can use the Break All option to terminate any running scripts. If no script is running, it will break the moment a script is executed, such as if you hover over an element with the mouse that has an onmouseover listener.
This might get somewhat cumbersome if you are looking for a specific piece of code. I don't think there's really a way around this besides just tracing through the code until you find the part that's relevent.
If this is a bug that happens when you click on a button, for example, look at the HTML code for the button. If it has an onclick handler, search for that function and set a breakpoint there, or add the word debugger; to the top of the function. If there is no onclick handler, search for the ID of the button in your Javascript code and see if any listener is bound to that DOM element.
There's really no reason why 12,000 lines of Javascript code should thwart your efforts to see what's going on. Find a repro for the issue, and then use Find to locate the relevant code in your Javascript file. Also, I realize your site might not work in Firefox or Chrome, but it might work in IE8 since it's fairly backwards compatible. IE8 has a better debugger and also the ability to explore various DOM elements which could come in handle for tracing what code is run where.
Hope this helps!
Further to this question, I'm getting a curious result when binding a function to the change event of the Storage object in Chrome 8.0.552.224.
The test:
<!DOCTYPE html>
<html>
<head>
<title>Chrome localStorage Test</title>
<script type="text/javascript" >
var handle_storage = function () {
alert('storage event');
};
window.addEventListener("storage", handle_storage, false);
</script>
</head>
<body>
<button id="add" onclick="localStorage.setItem('a','test')">Add</button>
<button id="clear" onclick="localStorage.clear()">Clear</button>
</body>
</html>
Open up the page in two Chrome windows, one window with two tabs,
Click the 'Add' button
When I do this I get an alert box displayed on on the second tab and on the second window but not on the tab that invoked the event (the I clicked on). As I understand it I should see three alert boxes (one for each tab opened).
Is this a bug? Is anyone else getting this behaviour? If not what version are you running? Or have I just got this all completely wrong?
Update and final conlusion
It turns out that the spec actually says that this is the desired behavior, therefore IE9's implementation is broken.
4.2 The sessionStorage attribute
When the setItem(), removeItem(), and clear() methods are called on a Storage object x ... if the methods did something, then in every HTMLDocument ... [that is] associated with the same storage area, other than x, a storage event must be fired....
So as we can see, the spec does do a really bad job at making it clear, that this is the specified behavior. That was the reason why Opera 10's implementation was broken and it's most likely also the reason why IE9's implementation is broken.
What do we learn from that? Always read every, single, word of the specification (especially if you're implementing the stuff...).
Old answer
As you said the basic behavior here is "Invoke on all but the current page".
There's an old Chrome Bug Report from last July.
As one can read there, Firefox has the same "issue". I've tested this with the latest nightly, still behaves the same way like in Chrome.
Another test in Opera 11 shows that this must be some kind spec'ed behavior, since Opera 11 does the exact same thing but Opera 10 did fire events on all windows / tabs. Sadly the official changelogs for Opera 11 do not state any change for this behavior.
Reading through the specification, nothing there states this behavior. The only thing I could find is:
The storage event is fired when a storage area changes, as described in the previous two sections (for session storage, for local storage).
When this happens, the user agent must queue a task to fire an event with the name storage, which does not bubble and is not cancelable, and which uses the StorageEvent interface, at each Window object whose Document object has a Storage object that is affected.
Note: This includes Document objects that are not fully active, but events fired on those are ignored by the event loop until the Document becomes fully active again.
Well, what does the Note mean?
From another specification:
A Document is said to be fully active when it is the active document of its browsing context, and either its browsing context is a top-level browsing context, or the Document through which that browsing context is nested is itself fully active.
Doesn't make sense? Yes. Does it help us in any way? No.
So we (in the JavaScript Chatroom) poked on #whatwg to see what all of this is about, so far there has been no response. I'll update my answer as soon as we get any response.
To conclude for now
Firefox, Chrome, Safari and Opera have the exact same behavior. That is, they do not fire on the tab / window that made the chance to localStorage.
But IE9 Beta behaves like Opera 10, so it fires on all tabs / windows.
Since the author of the localStorage spec works at Google in R&D, I hardly doubt Chrome would get this wrong. And since there are no Bugs on this over at Bugzilla and Opera changed the behavior in 11, it seems that this is the way it should work. Still no answer why it works this way and why IE9 behaves differently, but we're still waiting for a response from #whatwg.
Ivo Wetzel's answer for what is going wrong is correct.
I was having the same problem but managed to work around this limitation in the spec by manually creating and firing a StorageEvent in the tab that initiated the storage change (see StorageEvent#initStorageEvent).
Learning client side code of an existing site, would like to understand some activity that takes place totally at the client side.
Want to know what JS handlers are being called when I click on a specific element. Is there a way to see this information in some kind of debugger?
I'm using Firefox with Firebug, or Chrome
You can use the Chrome Developer tools to do what you are looking for if I'm reading your question correctly (apologies if I did not). In Chrome, right-click on the element in the rendered page and choose "Inspect Element". On the right side of the tool window that opens there's a section called "Properties" that will pop down a list when clicked on. Investigating the sub-categories should show you what functions are hooked up to what events. You can then use the "Scripts" area (tab at the top of the Development Tools window) to set breakpoints and observe the behavior in script files. Hope that helps.
Most sites will use some sort of Javascript framework which uses their own event management system, rendering firebug's or chrome dev tool's DOM inspection tools rather useless.
Luckily it isn't too difficult to tap into the event systems of these frameworks. There's FireQuery, which is an extension for Firebug that integrates very nicely with Firebug's DOM inspector, but it works only for jQuery. For other frameworks, there's also Visual Event