Unable to edit javascript in Chrome dev tools - javascript

I am attempting to edit some javascript code that is in the html of the page (not an imported js file). I am able to set break points and step through them, but I can not edit the javascript during the execution or before/after execution. I prettified ({}) and un-prettified the files. The code piece is not minified in this section.
Can I do this?
Does it matter that the code is inside an attached event. Ie a click etc.
I am useing jquery obviously.
I could have sworn this used to be a common feature. But it has been over a year since I have done a lot of javascript.

Using chromium / chrome there are several methods to modify the html of an existing document. At devtools
Select Elements tab, right click on the element to modify, select Edit as HTML , make modifications in frame containing element, then click outside of editor frame
Select Sources tab, select Snippets tab, right click and select New , write javascript, to execute in existing window press ▶ at right panel to run javascript in Snippets middle panel in existing window. For example if $("body").on("click", function() {alert(123)}) is added as a Snippet clicking body element should call alert(123). The event should also be listed in Event Listeners at right panel of devtools when inspecting element. Removing the listener may be somewhat more challenging; even if you click remove when hovering over the listener at right panel, as the event is already attached to the element. The simplest method would be to add a namespace to the event $("body").on("click.abcnamespace", handler), then call $("body").off("click.abcnamespace")
Modifying text existing handlers will not automatically affect , or cancel the event handler previously attached to the element. The simplest approach would be to copy and save existing javascript containing event handler, select Elements tab , right click on element that has event listener, select Event Listeners at right panel, when hovering over the window, document or HTMLElement having event attached a button should be displayed that says Remove. Click that button to remove the event listener. You should then be able to modify the saved event listener and add it back to the existing document with modifications being applied

Related

breakpoint doesn't work on button or div element but works on li element

I'm new to JS and trying to understand code of project https://github.com/tastejs/todomvc
Refer to screenshot, I tried to put breakpoint against button X , later its parent element div but in both cases execution doesn't stop when I click on X button. ( tried all 3 options under breakpoint )
It only worked when I put breakpoint at element li; chose option node removal.
Please explain what mistake am I doing here ?
Well, the reason the breakpoint is not working on when you are clicking on the <button> or the <div> containing the button is because there is no change to the DOM after clicking the button (seeing as the only breakpoint options, other than on node removal, are on subtree modifications or on attribute modifications).
The reason the on node removal works on the <li> is because (as far as I understood of the project you are using) when clicking on the button, you start a block of JS code that will remove said element (the <li>).
Still, if you want a way to get a way to actually add a breakpoint when clicking on the button, I suggest using this method:
in Chrome Dev tools
go to Sources
look at the bottom half of the window and find Event Listener Breakpoints
find and expand DOM Mutation
enable DOMFocusIn
click on your button
Caution: this will cause a breakpoint to appear whenever an element is focused (not just clicking on the button) and as probably you know some elements in the DOM can gain focus.
Hope this helps.

HTML onClick VS jQuery mousedown Timing

I'm working with legacy HTML pages written ~10 years ago. That being said, it should be explicitly known that refactoring old code is not only NOT time effective, but also a risky endeavor.
A legacy webpage has many buttons which activate JavaScript event(s) using the onClick="myFunction()" tag. I've been tasked with interfacing a JavaScript file (which uses jQuery) into these legacy webpages. I've added the JavaScript file in question and jQuery 1.9.1 source and attached them to the legacy HTML pages prior to the closing body tag, ex:
<script src="jquery-1.9.1.min.js"></script>
This JavaScript source file (which uses jQuery) activates a mousedown event on the buttons with the attached class "getStats", ex:
$(document).on('mousedown', '.getStats', function (event) {
//Stuff
});
However, when the jQuery activates, it does NOT perform the redirect the button is supposed to do through the HTML onClick event.
I can't find any information online on how the HTML onClick and jQuery mousedown event timings happen to understand whether or not I'm encountering a race condition. Both the HTML onClick redirect and jQuery mousedown events need to happen, and I can't just simply go back and edit all the legacy HTML onClick events to be done in jQuery either as that would take months of work.
Sample jsFiddle:
https://jsfiddle.net/koa2hsbp/
The jQuery works right off the bat. If you comment out the jQuery mousedown function, then the HTML onClick works. But I have to make it to where both parts activate (preferably jQuery mousedown prior to HTML onClick), without changing the HTML's functionality. (Again, changing the legacy code is a costly endeavor in and of itself.)
Some explanation about events:
mousedown - triggered immediately after mouse button pushed down while focusing element.
mouseup - triggered immediately after mouse button goes up while focusing element
click - triggered when you have consecutive mousedown+mouse up on the same element.
So in your example - you push mouse down and this immediately triggers code which produce alert. Then you release mouse button, but web paged is focused on alert, not on our element as alert window by nature blocks everything else and interrupt javascript. Since there is no mouseup event - there is no click event as well, so legacy code is not invoked.
Try following to prove I am right - push mouse down and hold it. Then click enter button - this will remove alert. Then release mouse button while on top of element. This will trigger click.
Unfortunately it is hard to mix mousedown click and alert in same example. Consider moving jQuery handler to click if you need alerts. That of cause will invoke jQuery after legacy handler.

HTML / JS : How to trace the event handlers and corresponding files

I need to trace every event-handlers associated to every events of a HTML DOM element for example Button in browser like Chrome or Firefox. I also want to know which file contains the event-handler function.
I work in Rails framework and jQuery. I have so many JS file to manage. Its very troublesome to find the culprit when some thing in client side goes wrong.
Can some one help me in this regard?
You can use Chrome Dev Tool to look up event listeners added to any element, which looks like below.
Right-click the element you'd like to inspect (e.g. some button)
Choose 'Inspect Element' in the context menu
Select 'Event Listeners' Tab (shown as 1 in the screenshot)
To filter listeners only bound to the selected element, set filter to 'Selected Node Only' (shown as 2 in the screenshot)
Click the link represented in the right column of the list to get to the listener source code. (shown as 3 in the screenshot)
See also: https://developer.chrome.com/devtools/docs/dom-and-styles#viewing-element-event-listeners

Without the file or function name, how do I find a function that is making changes on an element?

I have a large project. With dozens of JS files. An element on my page has a click event attached to it. I want to edit this click event, but first I need to locate its' file & line. How can I do that, without knowing the function name or file name before hand? Is there a way to watch the element in firebug and record the function being executed?
Backstory:
The element has an .open class being added when it is clicked, and removed when the user clicks on anything else. I want to have that .open class added on mouseover, and removed on mouseout. I want to use the same function being called in the click event, but first I need to find it.
Thanks.
If you are using jquery to add the event you can find the handler of the event using this code in firebug's console:
jQuery._data($(".someHTMLelement")[0], "events")
You will find the location of the handler under the "handler" property, just click on the function to jump to the corresponding line in your code.
If you are not using jquery but a native addEventListener you can use this:
getEventListeners($(".rs-btn")[1])
The function will be under the property "listener"
If you neither know the file name nor the function name, you can make use of Firebug's HTML panel's Break On Mutate features.
This can be enabled for all elements using the toolbar button () or for a specific element and a specific action via the context menu.
While that option is enabled, trigger the JavaScript that causes the changes to the element. This will then stop the script execution at the line where the change happens.

What's the most efficient way to handle displaying a dialog/modal in JavaScript?

[UPDATE:] here is a link to test (if you don't want to clone the repo) http://jsfiddle.net/integralist/g9EPu/
I've got a lot of dialogs/modals that need to be displayed when mousing over certain links in a web app.
Table of content (tl;dr)
How I used to do handle it
How I've tried it recently
Which is better?
What about mouseenter/leave?
How I used to do handle it
The way I usually do this is to use event delegation.
So I add one event handler to a container and then check for the relevant element to become the target and then display the relevant dialog.
I normally have one dialog which I change the content for and re-position (saves having lots of different HTML mark-up).
If the mouseover event (for the link) gets triggered then I display the dialog.
If the mouseout event (for the link) gets triggered then I hide the dialog.
If I mouseout of the link which triggered the event handler then I normally need to set a timer to delay hiding the dialog (just long enough) so I can then mouseover the dialog which itself clears the timer set by the mouseout of the link.
I then have a mouseout event bound to the dialog so I can then hide the dialog when the user rolls their mouse off the dialog.
There are two problems I've encountered at this stage, the first happens practically all the time and the other is an edge case I noticed recently which prompted me to try and find a better solution...
The dialog has 'x' number of child elements and rolling the mouse over a child element causes the mouseout event for the dialog to be triggered hence I need to put in checks to see if the element has a parent which is the dialog itself and if so then don't try to hide the dialog.
When using this technique on a <table> element I've found that when the mouse moves too quickly the mouseout/over events don't get triggered.
How I've tried it recently
For example code see: https://github.com/Integralist/Mouse-Over-Out-Script (you should be able to just clone the repo and run the index.html file locally to see what's happening)
But to give a brief explanation...
We bind a mousemove event to the document.documentElement element (but you could do it on the document.body if you wanted) and then we store the x/y co-ordinates of the mouse position. We provide public API access to a 'check' method which lets us know if the position of the mouse is over the element we've provided to 'check' (we measure the elements dimensions and add those onto its x/y co-ordinates).
In the above repo we have a calendar which shows a dialog whenever a particular date has an event on. We're storing all <td>'s that have an event and we set-up a timer for each of those <td>'s (this is because we need to keep calling the 'check' method to see if that <td> has the mouse over it).
So potentially there could be 31+ (because we're showing the first few days of the following month) opportunities for a dialog to be shown and so 31+ timers set!
This example repo works now, where as the first version where I was using event delegation wasn't.
Which is better?
I'm worried about performance on the mousemove version because it can potentially use a lot of timers (depending on how many dialogs you need in a single page). In my calendar example above there is up to 31+ timers that could be running!
What about mouseenter/leave?
I know these events exist and if all browsers supported it then I could safely use the first version and not have to check for child elements causing erroneous mouseout/over events to be triggered. But regardless I don't believe this would have fixed the example with the event calendar where moving the mouse too quickly was meaning the mouseout/over events for the <td>'s weren't being triggered by the browser. Either way, I know you can polyfill this as jQuery provides mouseenter/leave events but looking through their code I couldn't get that to work for my script (as I don't use jQuery or any other general purpose library - ps, and I don't wish to, so please do not suggest that as an option).
Many thanks for any help/advice or guidance someone can provide me.
The dialog has 'x' number of child elements and rolling the mouse over a child element causes the mouseout event for the dialog to be triggered hence I need to put in checks to see if the element has a parent which is the dialog itself and if so then dont try to hide the dialog.
To solve this: in your event code, simply use the function "isAncestor" (see below)
/*
* element = the "target" in your mouseout event handler
* other = the node you really want to check if you're over
*/
isAncestor: function(element, other)
{
while ( element && element != other ) element = element.parentNode;
return ( element != null && element != undefined );
}
So in your mouseout code for your element (let's call it "itemElement"), you'd check it like:
//We're really mousing out, close dialog
if ( !isAncestor( mouseOutEvent.target, itemElement ) )
{
...do something ...
}

Categories