Imagine that there's a button on one web page (not mine) and when it's clicked it performs some
Javascript. I want to have a button on my web page that performs exactly the same. So I need to
attach all necessary js files (but first I have to find them) to my html page and sometimes add some js to my html page.
What I usually do in this case? I inspect this button html element to see if there's onclick attribute for this button. If it is, I see the function called when button is clicked and then I try to search for this function in current html page and all js files attached to page. Also I need to find all dependencies (like jQuery, fancybox etc.).
If the button doesn't have onclick attribute I have to look for direct getElementById or jQuery selector pointing to this button with rest of code there. Sometimes there's no such a selector and I have to find a nested selector - really hard and annoying thing.
Is there any better, automated way for doing things above. Ideally after selecting the element in DOM (button in this case) and pressing some magic button I will be able to see all js files involved in processing this click and also js code in html page.
It's going to involve digging no matter what you do. But Chrome's Dev Tools can help with the attached event handlers, to an extent. When you right-click an element and inspect it, on the right-hand side there's a panel showing various tabs: [Styles] [Computed] [Event Listeners] [DOM Breakpoints] [Properties]. The [Event Listeners] one shows the listeners directly attached to that element. Of course, on a site using jQuery (which is more than half the sites using JavaScript at all), looking at the handler will dump you into the jQuery event handling code, but it's a start.
Just as a side point: While it's fine to look at the source of pages for inspiration, or to see how they solved a particular problem, or what plugins they're using to get an effect, etc., I assume you're not grabbing large sections of their actual code (as opposed to libraries and plugins with liberal licenses) without their permission, which is probably not cool.
Related
Background:
I often find myself in the position of debugging a piece of Java script on a web page in an unfamiliar codebase, and often one that has seen many developers and coding approaches. Sometimes I do not even what technologies might be in use, eg. angular etc.
The first time I need to address the Java script is when a specific behaviour is unexpected (ie. it has gone wrong.)
Question:
What tool provides the fastest route to identifying the entry point of the code that is causing the problem?
Example:
I have an html element on a page lets say a button. When that button is clicked I expect to see an http request at the server. There are many ways the element can be associated with its Java script listener. eg JQuery, thrid party plugins such as knockout etc, in house scripts, and so on.
Using developer tools I can start debugging this in the browser but only if I already know the entry point to put a breakpoint on.
Is there a faster method to find the entry point than doing regular expressions searches on the pages code based on intuition and guess work to find what might be attached to that particular element?
For me, the best starting point is in Chrome developer tools. You can:
Choose an element in the elements tab
On the right-hand side of the elements tree, click the "Event Listeners" tab.
Find the event you want to debug (like click)
Click the hyperlink to bring up the code for event listeners, and set breakpoints. Sometimes you have to click the "format code" button (looks like { }) to get the code on multiple lines so that the breakpoint is manageable.
Do the click, and you'll hit your breakpoint, allowing you to step through the code, add watch variables, etc.
I'm coding in MeteorJS
I'm using a bootstrap based theme.
The dropdowns etc based on bootstrap, driven by plugin javascript code, don't work. Javascript code I write separately (to handle a login button, for example) does work.
There are no errors generated in the console at any time.
Any idea on the potential issues/how to debug this?
The most commom issue by FAR is the unique way that Meteor renders pages.
A normal theme is created with a traditional load order in mind:
a browser goes to a page and starts to parse the HTML from TOP to BOTTOM
As it goes from top to bottom it builds the DOM nodes of the page.
The browser loads the scripts tags that are down at the very bottom of the page, after most of the HTML code.
99.9% of the time these scripts at the bottom of the page require certain DOM nodes to be in existence for them to work. In the traditional top-down approach, this isn't a problem because all the relevant HTML is above these script tags.
Meteor does not have a top-down approach. If anything, it inserts sections of HTML into the page at different times, which means if you are coding in a top-down way, it's highly likely that at least some of your theme's script files get loaded before the HTML that they need to run are rendered on the page.
Your example of a login button event handling is a perfect example.
You first need the browser to parse
<button id="login-button"></button>
into a DOM node so that your accompanying event handler can work:
$('#login-button').click(function(){ //do something});
What that code is doing is first looking for something with #login-button, then attaching a click event listener to it. If #login-button doesn't exist by the time it runs, it has nothing to attach the listener to, and therefore your event handler won't run when the button is eventually clicked.
I've been playing around with the Material Design Lite library that Google just launched a few days ago, but have some questions, specifically on how to initiate (or execute?) external JS when the HTML changes using innerHTML and appendChild.
See the first example here. As you can see, the HTML for the menu is already within the HTML file when it is first loaded so the menu works fine.
But in this example, the HTML of the document is modified using JS. However, the menu does not work anymore because the script is not executing, I think.
How can I resolve this issue? What's a better way to achieve this result? I'm a newbie when it comes to JavaScript.
You will need to attach the proper event listener from the library. With this change (adding componentHandler.upgradeAllRegistered(); after appending the item) it should work:
document.body.appendChild(menu);
componentHandler.upgradeAllRegistered();
When the menu button is inserted dynamically (when the user clicks), it doesn't get assigned the event listeners to show the menu. I'm guessing that the material design library parses the HTML when it (the library) gets loaded (since you're loading it at the bottom of your HTML document). Since it's already loaded by the time the user clicks, it doesn't check the new element that has been inserted and can't assign it the event listeners.
If this is the case, you'll need to find a way to get the library to recognize your new button.
Is there a tool (or something in firebug) that will tell me what events just fired and more importantly on what elements they were bound to?
I have a number of javascript "includes", some minified, some not. I am experiencing some odd behaviour that I want to turn off, but I cannot find what is causing it.
I have a form showing in a "popup" and when I try to click on one of the input boxes, the "popup" closes, so some event bind somewhere is causing this.
The problem is, I don't know what element has this spurious event bound to it. The problem also occurs if I click anywhere inside the popup (and on the background mask that is covering the rest of the page, but that's acceptable)
I am using firefox, so anything I can type in the console is also an option. The eventys in the multiple javascript files are done in various ways, some through jquery, some using inline attributes (eg. onclick="..."), some using just javascript.
I certainly don't want to go and add some line of code to every possible event in every javascript file.
I have spent over an hour trying to hunt down this dom element and have already eliminated the obvious ones like the divs containing the popup and the body tag.
DOM modifications can be tracked down using the Break On Mutate option within Firebug. It can be activated by clicking the related button ( ) within the HTML panel. Note that the Script panel has to be enabled for this to work.
There are also several other Break On ... features, which may help you finding the right position within the code for a specific event.
Furthermore Firebug 2.0 introduced an Events side panel, which displays all events bound to the element selected within the HTML panel. If libraries like jQuery are used, it will even allow you to investigate the user-defined function wrapped by the library function in case you enable the option Show Wrapped Listeners as described in the answer to a related question.
I've got a pretty big complicated HTML5 app I'm working on (backbone, marionette, jQuery, underscore, handlebars, bootstrap, etc) and deep within the app is a modal popup with a form in it.
When the modal pops open, the first time you click on any form field the form field de-selects itself. After that first click you can use the form as normal. When the app is ultimately loaded into an iFrame in production (don't ask) the first time you click on any form field or hover over any button, the whole page scrolls down until the top of the div element the form is within inside of the modal is at the top of the page, but after it does this once, it doesn't do it again (confused yet? Yeah, it's complex and layered).
I'm at a loss for how to even begin debugging this problem (thousands of lines of code, two handfuls of libraries).
I tried these:
console.log('bound events: ', $._data(this.$el.find('#RandomFieldID')[0], 'events'));
console.dir($('#elmId').data('events'));
console.log('bound events: ', $._data($('body')[0], 'events'));
But that yielded nothing.
Since this is library upon library upon framework upon framework I'm not even sure where to begin trying to find the thing that has obviously bound itself to these fields, or even if it is the fields that are being bound to or something else entirely...
So, any suggestions on good strategies for how to debug a mysteriously bound Javascript event (with multiple JS libraries and frameworks, which can't be just commented out until the problem resolves because they are relied upon to even get the HTML to appear on the page in the first place)?
And, unfortunately I can't do a jsfiddle or something because, as I said, this is deep deep within the app and I'd basically have to re-create the app inside of JSFiddle (impossible) to link to an example (and, it's not in an external facing site, so, I can't just link to it live in production).
I'm stumped.
Here's how I do it with Chrome.
Ctrl-Shift-J to open Javascript console.
Click the little magnifying glass in bottom left, it lets you select an element with your mouse.
Click an element on your page (it will highlight as you go to it.) It will highlight in the DOM at the bottom and show a bunch of properties on the bottom right.
At the bottom right go all the way past the CSS attributes and stuff down to event listeners:
Pick the event listener you're interested in. It will show you the bound function as well as the exact line of code in what script would be executed. That should tell you what library is doing your crazy stuff.
I find the Chrome debugger to be much more powerful and fast (doesn't lag) compared to FireBug and the IE developer tools. It's highly recommended :)