Install it from the Chrome Web Store.
jQuery Audit is a Chrome Developer Tools extension for debugging auditing jQuery — it creates a sidebar in the Elements panel containing jQuery delegated events, internal data, and more, as live DOM nodes, functions, and objects.
- Variables in the
jQuery Auditsidebar behave like objects in theSources panel→Scope Variablessidebar. You can right-click on afunctionand goto "Show Function Definition", or hover over aDOM nodeto highlight it in the document, as well as right-clicking it to "Reveal in Elements Panel".
- The
documentand thewindowobjects don't have representations in theElements panelbut can nonetheless be event targets and/or have associated jQuery data.jQuery Auditadds two comment nodes above the<!DOCTYPE>to represent them. The<!--@(document)-->as a stand-in for thedocumentobject, and the<!--@(window)-->as a stand-in for thewindowobject. Select either to audit the represented object in thejQuery Auditsidebar.
Requirements: jQuery Audit does a typeof window.jQuery === 'function' whenever a node is selected. If it can't find a jQuery function in the global scope, the sidebar will display Error: "@(window.jQuery is missing)".
Tip: Text wrapped in @(...) are "messages" from jQuery Audit. This was the compromise made to get live objects in the sidebar and be able to show informative messages.
- The element currently selected.
- Data contains the would-be result of invoking
$(element).data().jQuery Auditdoesn't invoke.data()because calling it creates a data object in jQuery's internal store if one doesn't already exist for that element. Instead,jQuery Auditdirectly looks in the internal store for the data object and returns it. If there isn't one, you'll see@(none), or if it's an empty object you'll see@(empty Object).
- These are the events that the element would react to. That means any delegated events, or any directly bound events that don't delegate. (Directly bound events are under
Internal Data→events). For each event name, there is a corresponding jQuery event object associated with it, that has:- a
delegator: The ancestor element that delegates the event, or@(this element)when the event is directly bound to the element and there is no delegation. - a
handler: The function that handles the event. More often than not, thehandleris a bound function and not directly the function that does the "work". The section below on Finding bound handlers shows you where common binder functions store the bound function. - And more.
- a
- The internal data jQuery keeps on the element - it is the result of calling
$._data(element). This is not the same as the data object from$(element).data(), though the data object is kept here in the internal store.
- The value of
HTMLElement.dataset. This is not the same as Data above, but closely related to it.HTMLElement.datasetcontains the rawdata-*attributes. While Data is the parsed content of anydata-*attributes jQuery found on the element along with any other arbitrary information. (jQuery convertsBoolean,NumberandJSONindata-*attributes when you call.data()).
- The result of removing the
innerHTMLfrom theouterHTMLof an element. This helps debug character encoding issues, since what theElements panelshows is a decoded "pretty" version of the HTML and not the actual HTML.
Often event handlers are bound functions. In these cases, the function under Events → event_name → handler is the binder function and not the bindee. Depending on the binder used, the bindee function is usually near by.
_.bind from Lo-Dash
-
Expand the
handlerfunction followed by the__bindData__property. In this array, the first element is thebindeefunction, the other elements contain thethiscontext and any parameters to be partially applied. Older versions of Lo-Dash might not have this structure.
_.bind from Underscore and native Function.prototype.bind
-
Underscore uses to the native
bindfunction. A clear sign that thebinderis the nativebindfunction isfunction () { [native code] }for ahandler. Expand thehandlerto locate thebindeefunction is under[[TargetFunction]]. Thethiscontext is found in[[BoundThis]]and any parameters to be partially applied are in[[BoundArgs]].
$.proxy from jQuery
-
With
$.proxythebindeecan't be found as a property on thebinderbut rather in aClosure. Expand thehandler, followed by<function scope>and then the inner-mostClosure. One of the variables in this scope contains thebindee- the name of the variable that contains thebindeewill likely vary because of minification.
- Does
jQuery Auditwork with<iframe>'s?
Yes, if the
<iframe>has a jQuery function (regardless of the parent having jQuery or not) and it's not restricted by the same-origin policy.
- How do I remove
<!--@(document)-->and<!--@(window)-->?
Run
jQueryAudit()in the console. When you close the developer tools the twocomment nodesare removed and thejQueryAuditobject is removed.
- Why exactly the
@(...)?
The content of a
SidebarPanecan be an HTML page, a JSON object, or "the result of an expression". An HTML page, nor a JSON object, have the ability to display "live" objects. The reason for making this extension was so that I could find a delegated event and be able to use "Show Function Definition" on the handler. For that effect, the contents of the sidebar is actually "the result of an expression" with a lot of trickery to make it look not-so-ugly. So, to differentiate between actual object data and informational messages I went with@(...)so it wouldn't be easily confused with string data.
- Why the name Audit?
I am a lawyer. Yes, really. Went to law school, passed the bar, and I'm a fully admitted member of the New York State Bar Association. So, yeah, that's why Audit came to mind when I was thinking of a name.
Disclaimer: I am not related to the jQuery project.