I'm trying to use Firebug to debug some Javascript that entails blur and focus event handling, specifically some auto-complete/look-ahead functionality. The issue is that, merely by clicking on the various tabs within Firebug, such as "Console", "Script", "DOM", etcetera, the blur() event in my application is being fired, and then the focus() event when I subsequently click back in the text field that auto-complete is being driven by. The fact that these events are being unnecessarily being fired when trying to interact with Firebug, makes the debugging itself problematic if not well nigh impossible.
Has anybody else encountered this Catch 22, and/or does anybody have solutions/suggestions?
Use keyboard instead?
http://getfirebug.com/wiki/index.php/Keyboard_and_Mouse_Shortcuts
Also:
->options->show quick info box (then click inspect button) will show a capsule of info about everything you mouse over - if that helps
Could you switch them to debug. i.e. instead of using blur() and focus() use click() or hover().
not sure about your question, but as Alex said, you can still use the console to log events and any other javascript things.
For example
var x =5;
console.info(x);
x = 9;
console.info(x);
Run this code in your javascript and you'll see it in the console.
Had a similar experience trying to style a typeahead plugin. Best solution I found was right-clicking an element in the firebug dom and checking "break on child addition and removal" (you can also break on attribute change etc).
Related
I've noticed a rather odd behavior when running a unit test which passed on PhantomJS but occasionally failed in Chrome, Firefox and IE. In a nutshell:
I set a focus listener for a DOM element.
I invoked element.focus(), yet the listener was not run.
Calling element.focus() for a second time actually ran the listener.
Unfortunately I couldn't reproduce this issue in a fiddle, but it can be done, for instance, in jQuery's website. I do the following steps on Chrome:
Open www.jquery.com and then open DevTools.
Run $("input[name=s]").on("focus", () => console.log("a"));.
Run $("input[name=s]").focus();. No output is generated.
Run $("input[name=s]").focus();. Now "a" is printed to the console for the first time!
What is causing this issue and how could I work around it?
Had a quick delve around the jquery source code, and it seems that focus actually uses focusin, and the code is trying to map to focusin. so if you try this:
$("input[name=s]").on("focusin", () => console.log("a"));
$("input[name=s]").focusin();
it will work. There is a difference between focus and focusin around bubbling:
http://api.jquery.com/focusin/
The focusin event is sent to an element when it, or any element inside
of it, gains focus. This is distinct from the focus event in that it
supports detecting the focus event on parent elements (in other words,
it supports event bubbling).
It seems like the behaviour is a hard to replicate bug, that must be caused by other bit of code somewhere (maybe a lib). Although the code above should help work around it.
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
I'm using Firefox. Is there something out there that will show me all the JavaScript events that are getting triggered in real time?
You can right-click an element in Firebug's HTML tab and click Log Events.
You will then see every event received by that element in the Console tab.
You can even click one of them to explore the properties of the event object.
I have been using Visual Event for a few years now. It's a simple bookmarklet, meaning you just have to drag it into your bookmarks, and then click it while on your page to visually highlight all javascript events. You can also trigger the events at will, and probably a whole lot more. It's very easy and intuitive to use, and perfect to quickly find what you're looking for. Give it a try:
https://github.com/DataTables/VisualEvent
Scenario: I'm trying to intercept paste events inside a textarea/input text, and filter the content being pasted.
Webkit/IE are handled rather well, as I can attach code to the onpaste event, and then read from the clipboard what is being pasted. Plenty of examples around.
Gecko is trickier, because as far as I know it isn't possible to read the clipboard content on Firefox (unless somebody knows a workaround for that?)
I just use the input swap trick for that.
Opera is being annoying tho. I can trap CTRL+V and SHIFT+INS, but there's no onpaste event.
Not to mention any sort of clipboard interaction, apparently.
So, my question is:
Can I detect if the user clicked on paste in the context menu on Opera? Is there any other way to detect the event?
EDIT:
Thanks everybody for the answers - they all add a good input, even if there's no definitive solution.
Having to choose, I'll pick the only one that tried to address the original question, and that would probably work if it wasn't too much of an hack to even try.
Notes for those that have my same problem (input filtering):
it is possible to capture content being dragged: mouseup + setTimeout does the trick everywhere almost perfectly.
without flash, there is probably no solution bar polling. Even with flash, it's not a completely solid solution either. Too much effort to support 100% of the cases.
I ran into this last year. In short, no.
I ended up using an onchange handler and filtering the content after it's already been pasted into the text box.
You can intercept the paste with jQuery using the bind('paste', function() {});, compare string before and after pasting and apply your formatting.
The following was tested in IE7/FF3.6/Chrome/Safari 5
$("#textarea").bind('paste', function(e){
// Do whatever you needed to do with the code here.
});
Live Example http://jsfiddle.net/VSrTg/2/
Edit An approach would be something like this:
$("#textarea").bind('paste', function(e){
var oldText = this.value;
setTimeout(function() {
// Compare oldText to $("#textarea").val() and format accordingly.
}, 1000);
});
Edit 2 Given your revisions to your original post, if you're worried about the giant market share that is Opera, you're going to have to monitor the value of your textbox with a setInterval() and compare it against itself for changes.
Ultimately there will always be a way around your script, even the above example is susceptible to simply dragging text from another text box (or the address bar) into it without triggering the paste event defined above.
I would like to point out DOJO menu widget that is creating context menus perfectly in different browsers. http://www.dojotoolkit.org/reference-guide/dijit/Menu.html#dijit-menu
What you can do is that detect paste event in browsers that are supporting it and override context menu in browsers that are not supporting this event like opera.
Once you create your own context menu then you can add copy paste menu item or create context menu similar to the default using css.
Edited
Some browsers might not allow us to fetch clipboard content, in this case we can always revert back to flash for borrowing some of its features that are cross browser. See couple of links I posted in comments.
Its complete implementation might have more issues than anticipated but it is possible and we can always give it a try (I will for sure).
The answer to the question is a simple no. The main browsers that have no paste event are recent versions of Opera and Firefox 2. Given that there is no paste event, you need to find an alternative event or set of events to detect a paste from the context menu as it actually happens. You can add handlers for every event there is (I've done this) and you simply get nothing in the relevant browsers when a paste is triggered from the context menu by the user.
This only leaves polling the text input's value regularly, which is not the same thing. You could keep track of keypresses and observe in your polling code that the text input's value has changed by some means other than keyboard input and do a diff, but that's hacky and unreliable.
I use the setTimeout for paste events. But for context menu select nothing seems to work(as stated above). I bind a mousemove to the input's form which fires the update function. Then unbind/bind so they don't stack up.
This handles the context menu select and dragging value to input field.
If your form is small, say with only one input field and the mouse will not land on it after selecting from context menu, bind to the form's parent or document. Sure, it has to wait until the mouse moves but that is the general user action after selecting from context menu.
Works fine.