I've been wracking my brain over this and cannot figure it out for the life of me.
Here's a test page I built for the sake of this discussion:
http://jsbin.com/garokalocu
Let's assume this page is very complex and I didn't build it, and I'm trying to see the code that runs when the user clicks "Do It." So I open the debugger, open the side pane and click "Events." I checkmark the click event for #execute which is the button.
Now I click the button, and the code hits the breakpoint. But strangely, the name "Bob" has already been filled in, so clearly it flew right past the actual code, and lands me here:
I don't understand what's going on here. So I tried something else, a new feature in Firefox that I thought might be handy. If I inspect the code, there are little "ev" tags on certain DOM elements. Supposedly you can click those and see the code.
Well, that was fruitless. I'd be forever grateful if someone could please tell me how on earth to debug jQuery events, and see the actual code that gets executed. Thanks!
You see jQuery as the handler because you used jQuery to make those listeners. jQuery code is called when event is triggered. If you used normal JS addEventListener, they will show up in the event without having to step through.
According to the article here the feature is coming in Firefox 34, so if you use Firefox beta it should have the behavior you want.
Related
Is there any way to directly spot what line of code is being executed (javascript) when clicking a button in a webpage or scrolling down .. etc?
For example: Not onMouseClick function when clicking a button and doing debug via browser in the same time but some function like $('#xx').click() instead.
If so, How?
Thanks in advance.
I've always battled to find this feature in Chrome, I'm sure it's in there, somewhere but no one seems to be able to find it. In Firefox is quite easy: Inspecting an element will show if it has an event attached, and will even show the code. Clicking the arrow next to the file and line number will jump to that location inside the debugger.
I have a page with bunch of 3rd party JS scripts. When I load the page, it scrolls down to a specific div.
I already spent 2 hours trying to find out which code is causing the scroll.
Is there a way to find out which script / part of the code is triggering the scroll?
Wow, was this hard to debug. Seems like the debugger has some missing features, like tracking the emitter of an event.
The problem is WooCommerce. Specifically, it appears that WooCommerce is setting autofocus on the billing_last_name input field. The browser is then automatically scrolling the page to bring the field into view.
One would hope that there is a configuration option to turn off autofocus, but it appears WooCommerce does not provide this.
You can try adding this to your theme
function disable_autofocus_firstname($fields) {
$fields['billing']['billing_first_name']['autofocus'] = false;
return $fields;
}
add_filter('woocommerce_checkout_fields', 'disable_autofocus_firstname');
If that doesn't work, you can create a CSS rule to hide the billing name field and then run a delayed JS function to show the billing name field after the page is fully loaded.
How I debugged it
Per the OP's request, and considering the bounty offered, I will describe how I debugged this.
I'm a little embarrassed that I didn't just say to myself "Hmm, the page scrolls up to a form, the cursor is in the first field of the form, I wonder if it has autofocus set." Unfortunately, I'm not mainly a front-end programmer, and autofocus did not come to mind at first.
I started with the idea that it was being scrolled via JavaScript, either an explicit call to a scroll function or by setting scrollTop on something. I put an event breakpoint on the scroll event and tried to determine where the scroll event was being generated. Although I found the scroll event, I did not find the source of it. All I could determine at this stage is that the scroll event was targeting the document, not something inside it.
I used monitorEvents to listen for events on document and found only 3, a click and 2 scrolls, the last of which was caused by a delayed scroll-to-top function inserted by the OP to work around the first scroll. I put an execution breakpoint on setting that timeout (not executing the function) in an attempt to "divide and conquer", that is, to see if the scroll was happening before or after that. I maintained that breakpoint for the rest of my debugging effort.
The weird thing was that generally, the page would not scroll before it hit that breakpoint, but sometimes it did. I thought that was odd, and although I didn't know what to make of it, it had me on the lookout for something unusual.
I tried searching all the JavaScript for "scroll" and "update" (text) to look for more breakpoints to set, and set a bunch at JavaScript that did scrolling, but nothing hit.
I noticed that there was a lot of JavaScript dynamically updating the page, and thought that maybe the scroll was due to an update of some sort.
I tried putting a jQuery event listener that logged all events on document (since the JS was using custom events not logged by monitorEvents, and I had already determined that document was the target of the scroll event) to emit all the events and see if it was some custom update event. There were a bunch of custom events, and I later generated the events in the console to see if the page would scroll in response. Since I could not get the page to scroll that way, I concluded that events were likely a dead end.
I switched tactics. I looked at where the page was scrolling to, and saw it was scrolling the WooCommerce form into place. So, while stopped at the execution breakpoint (described above), I deleted the entire WooCommerce form from the DOM, and verified that the page no longer scrolled. This had me convinced that whatever the problem was, it was caused by WooCommerce.
Unfortunately, my Google Fu failed me, and I did not immediately find the problem through a Google search. Instead I found how WooCommerce scrolls the page on errors to make sure the error messages are visible. This led me back to the JavaScript.
Still, there was a lot of JavaScript, a lot of it dynamically creating the form (localizing it on the fly), and a bunch of German (which I don't speak), and I wasn't finding any JavaScript causing scrolling. I really wanted to narrow down which JS file was causing the scroll.
Chrome allows you to set a breakpoint on "script first statement" (under Event Listener Breakpoints -> Scripts), so I did that. In addition to stopping at the first line in every script file, it stops at the beginning of every <script> tag on the page. I found this script tag near the bottom of the page
<script type="text/javascript">
if(typeof jQuery == 'undefined' || typeof jQuery.fn.on == 'undefined') {
document.write('<script src="https://www.prored3.de/wp-includes/js/jquery/jquery.js"><\/script>');
document.write('<script src="https://www.prored3.de/wp-includes/js/jquery/jquery-migrate.min.js"><\/script>');
}
</script>
The weird thing about this script tag was that the scroll happened immediately after this script tag was processed, but jQuery was already loaded, so the script actually did nothing. I was also able to confirm via the console that both before and after this script tag (which is before and after the scroll), the DOM was not flagged as ready. This means that all the jQuery ready handlers had not run by the time the scroll happened. That eliminates a lot of JavaScript, and got me thinking about why the scroll happened after but not before this tag.
I guessed that internally, the browser saw the document.write calls and determined that the DOM was not complete until after it passed that tag, but as soon as it was past it, the DOM was complete and it could start processing page-level attributes. That, along with the earlier observations, led me to look at the WooCommerce form more closely and discover the autofocus attribute set on the billing_first_name field.
Oddly enough, I was not able to prevent the scrolling by deleting the autofocus attribute. I don't know why, but I'm guessing it has to do with browser internals and the fact that the DOM was not ready. I was, however, able to prevent the scrolling by hiding the the billing_first_name in put element via CSS, which convinced me it was the cause of the scroll.
Adding "autofocus" to my Google search led me to other complaints of similar behavior with WooCommerce, and combining posts led me to the PHP solution I posted.
Updated
As I don't have OP's page for testing, the following method of finding registered event listener actually DO NOT solve the issue OP is addressing.
However, this is the general method when I want to find a specific event, just reserved for someone's reference.
If I understand your meaning correctly, you want a method to tell you where do the specific events occur. Please tell me if this is not doing what you want.
You can try to add a breakpoint on chrome debugger.
F12 -> Sources -> Event Listener Breakpoints (in list with those Breakpoints, Scope, etc) -> Control -> Click the box of scroll.
For Sure it may captures some other scroll event you are not interested, but you can go through it next by next until you find the one you want.
Besides, there may be also event not related to scroll, you may also need to try focus or DOM Mutation -> DOMFocusIn.
Look at this fiddle http://jsfiddle.net/52VtD/2635/
Inside it you can see one tooltip working.
Suppose we weren't looking at a fiddle though, and couldn't see the javascript source, but we wanted to know what was controlling this tooltip behavior?
The answer is
$("#tooltip1").tooltip();
So how do we find that answer using chrome or firefox inspector, or some other debug/browser inspector stuff? Preferably it would be quick, as opposed to downloading all .js files and prettifying them in an IDE and then manually searching.
There is no quick answer to this. You pretty much have to analyze a specific situation and see what clues you can then go look for.
In this particular case, you're going to suspect that there's an event listener attached to the #tooltip object. You can first look in the Chrome debugger for event listeners. Right click on the button, select Inspect Element, click on the Event Listeners tab and then look at the event listeners. In this particular case, you will see a bunch of them for that object. What you want is mouseout and mouseover. But, when you see where the event listeners are attached, it just take you to the internals of jQuery. This is a challenge with a library because it's the library that actually attached the event as part of some higher level API that the developer used.
So, now you know that jQuery was used to attach these events. You need to figure out where in the code these events where attached. To do this, you need to develop a theory about how the developer identified this particular object in jQuery. Since there is no particular structure to this simple document, the likely way that the developer found this particular object is with a "#tooltip" selector passed to some jQuery function. So, at this point, I would search all the JS in the page for "#tooltip" and see what you find.
While still in the Chrome debugger, you can hit Ctrl+F and enter #tooltip. Then, hit enter several times as it takes you to different uses of that and the third time, it will take you to:
$("#tooltip1").tooltip();
And, you will have your answer. Obviously, every problem like this is a bit different and it takes some detective work and searching to figure out what clues to search for in the Javascript. Some cases are much harder than others.
In *Chrome** you can bring up the developer tools buy clicking f12 and on the right you should see a tab titled "Event Listeners". Here you should see the event listeners for the page your are on.
This should have all the Event Listener info you could ever want :)
Using Chrome's developer tools I am trying to determine what jQuery function is hooking an input button on the page for debugging purposes. I usually just keep searching until I find it, but I figured I'd ask this time.
Is there a way to find a jQuery button hook for a specific button in Chrome? I've tried looking through the Event Listener Breakpoints, but can never seem to find the right thing to pause it.
Basically, I need to know what jQuery / Javascript is being executed after the button is clicked.
The hooks are implemented in the application like so:
$('.button_class').click(function (){
$('#button_id').click(function(){
etc...
try this :
$(yourbutton).data('events');
Depending on the number of events/timers on the page this doesn't always work. But you can try "pausing" before clicking the button you want to debug in the JavaScript debug window. That way the debugger will pause on the next line that executes. The thing that occasionally prevents you from using that is if there is a "hover" or mouse move/in/out event tied on an element you have to pass over to get to the button (including the button itself). In that case I just remove those events (if I can) until I get the one I want. The event listener breakpoints would be more ideal but they're sometimes difficult when using jQuery or another library, I've actually put in a feature request to the Chrome Dev Tools team to address this very issue. (allowing you to specify what files are "yours" and only "breaking" in those specific files)
good luck -ck
So I have looked through most of the facebook questions here and it has absolutely confirmed my thoughts. Facebook development may be among some of the worst I've ever used. I'll avoid my rant for now, but as a note to where I'm coming from: tried php sdk, worked decently out of the box, found out I need to put the functionality on a pages tab, can't iframe on pages tab, have to use FBML (which they are retiring in two months, yet I can't start testing the iframe approach yet)
Anyway, I run into FBJS at this point. It works "good enough" for most things, but for some reason I can't get an event registered to an object (a select box in particular interest) by adding a listener (as per FBJS documentation). I am able to add it directly to the html object and have it work, but this is not desirable and I would really like to know what I consider the proper way to do it, which involves seperation of logic and display.
What I want to happen: click on the select box, make a selection, display the text of the selection in an empty div (later on adding Ajax but one step at a time here)
Code:
<script>
var obj = document.getElementById('select-id');
obj.addEventListener('onchange',my_func);
function my_func(evt){
var inner = document.getElementById('div-id');
inner.setTextValue('hey'); // for testing purposes
}
</script>
The above code doesn't do anything when I make a change to the select box. However, this behaves as planned:
<select name="find_state" id="find_state" onchange="my_func();">
I will be grudgingly using this method as I develop, but would really love to know what I might be doing wrong or if anyone else has this issue? And if anyone has any opinions on the matter I would love to know of some form of facebook development recommendations as applications, pages, and tabs all appear to behave totally different from eachother, yet it seems that they all should be doing the same thing to me? Is there any unified way to develop across all three of these things, or am I missing something?
Thanks in advance, as well as for the past help!
I think it should be:
obj.addEventListener('change',my_func);
(instead of onchange)
Straight from Facebook documentation:
The third parameter [to addEventListener], boolean useCapture is required (it does not have a default value)
That means that you should have:
obj.addEventListener('change', my_func, false);
Use the following html and your events attached with .addEventListener() start to work. This seems to be undocumented "feature".
<select name="find_state" id="find_state" onmousedown="return true;">
This also enables the event to fire first time the user changes the value of select. Otherwise it would fire only on second onchange event.