Chrome: Debug who changes document.location.hash - javascript

I'm analyzing a site where the document.location.hash changes after some seconds since page loaded. It seems something asynchronous.
Is possibile to debug who change the hash, via Chrome inspector?
By now I only add a "watch" but is hasn't breakpoint.
Thanks

You can enable an event listener breakpoint for "hashchange":
As of 2019 Q4, this functionality exists in the "Sources" tab, in a panel titled "Event Listener Breakpoints".
When code now makes a change to location.href Chrome would stop at a handler for this event:
You can now go to the cause using the "Call Stack" panel.
This only works when there's already an event handler for hashchange.
Assuming you don't have such an event handler in your code yet, create an event handler like this:
window.addEventListener("hashchange", function(e) {
debugger;
});

Related

Chrome popstate not firing on Back Button if no user interaction

I'm trying to use "pushState" and the "popstate" event to trap Back button navigation, however, while the popstate event triggers correctly in Firefox, it doesn't trigger in Chrome (Version 76.0.3809.87 (Official Build) (64-bit)) if there is no user interaction.
From testing, it looks like the popstate event only gets triggered if the user interacts with the page (ie. clicks somewhere on the document). So if you load the page without interacting and hit Back, the popstate function is not called.
I've added a Fiddle to showcase this: https://jsfiddle.net/0xwvLndu/
To test the Fiddle in Chrome, just click the link and hit the Back button. You'll see no alert. Then click the link again but this time click anywhere on the Fiddle document and then hit the Back button, the alert is then triggered.
I found a discussion on the Chromium forum that may relate to this quirk, and perhaps this has been implemented to prevent abuse of history entries - https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/OCS7g72HtyI and https://github.com/WICG/interventions/issues/21#issuecomment-425609246
If this is the case, does it mean that popstate cannot be relied on anymore to trap Back button actions, and if so, is there a work around solution?
Below is an example of what I've been testing with:
window.addEventListener('load', function() {
history.pushState(null, null, document.URL);
});
window.addEventListener('popstate', function(event) {
alert('test');
});
I expected the alert to be triggered on Back Button regardless of user interaction, but this does not happen in Chrome.
Try adding a setTimeout of 0
window.onpopstate = () => setTimeout(alert.bind(window, "Pop"), 0);
When writing functions that process popstate event it is important to take into account that properties like window.location will already reflect the state change (if it affected the current URL), but document might still not. If the goal is to catch the moment when the new document state is already fully in place, a zero-delay setTimeout() method call should be used to effectively put its inner callback function that does the processing at the end of the browser event loop: window.onpopstate = () => setTimeout(doSomeThing, 0);
Content is taken from
https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event
On a sidenote it is advised not to use this as browsers may remove this any time.
As others suggested in comment, this should be by design of browser software to prevent hijacking of its default back button behavior.

Same Click Event Handler Registering Twice

I'm trying to solve a Bootstrap ScrollSpy issue where clicking the tab links is not doing anything (though scrolling properly highlights the tabs). I noticed that the same Bootstrap click event handler is showing up twice in Chrome Developer Tools (I've verified that if I click on each of the links, it brings me to the same line in the same file).
Why would the same exact click handler be appearing twice? I've also verified that Bootstrap is only being included once.
Try clicking that bootstrap.js link that you're pointing to in your screenshot, and adding a line-of-code breakpoint on the line that registers the event listener. If you think that the event listener gets registered when the page loads, then reload the page. The page should stop because of the breakpoint. The Call Stack pane should help you figure out why the event listener was registered. Resume script execution and you should see the event listener get registered again. If the event listener doesn't get registered on page load, then just interact with the page in a way that you would expect to create the listener.
See Get Started With Debugging if you're unfamiliar with stepping through code with DevTools.

Accessing full path of object mentioned in Chrome console

I am using Chrome's DevTools JS console to debug a custom function that executes when a button is clicked. When I click on the button, I get the following message in my console:
[Violation] 'click' handler took XXXms
Is there a way I can access the full path of this (button) object that I am clicking through the console message I am getting? I assume it will be something along the lines of App.controller.XXX.
Workaround:
Enable a event listener breakpoint on Mouse > click.
Click the button. DevTools pauses in the button's click handler.
Evaluate e.target in the DevTools Console, where e is the name of the event object that you're passing to the handler. In other words, you might have used the name event, e, or something else.
Right-click the DOM element that gets returned and select Reveal in Elements panel.
As per wOxxOm's suggestion, I have opened an issue into crbug.com as a feature request since what I am asking for is not yet possible.
Follow the issue here.

Google Chrome extension (Fire a event when extension starts)

I want to fire a event just when my chrome extension starts. How do I achieve this? Is there a event listener that triggers when extension starts?
for example:-
chrome.runtime.onInstalled.addListener(function(){
console.log('i will run once!');
});
Similar to this but not on installed but on start and it should only fire once during the extension's run time which is when it starts.
You could use an onload event in your background page and put the code that you want to be executed on extension "start-up" in there.
Example (inside background.js):
window.onload = function() {
console.log("Extension has started...");
};
That message will be logged (once) when:
Extension is installed
Chrome is started (and extension is enabled)
Extension is enabled from disabled state
Do you mean "onStartup" event?
chrome.runtime.onStartup.addListener(function callback)
See Google documentation here
Just place any code to background.js and it will execute when extension starts
console.log("extension starts");

BFcache disabled by unload events (Back-Forward cache)

(Note: FireFox only)
The Back-Forward cache is a caching system in firefox that runs when the back button is clicked. It will then simply use the DOM from the previous page that is in it's cache instead of reloading the entire page (and re-requesting files).
I'm using piwik (an analytics service), that requires a tracking code snippet to be added to the footer. Upon adding this, the back-forward cache no longer works.
It is my understanding that, if there is an unload event (or beforeunload) the bfcache is automatically disabled. This is likely what is happening here.
Is there anything I can add to make the BFCache work anyway?
To make matters worse, I cannot add any custom code below the piwik code. That one is always last.
I added the code displayed below to try and remove any unload events that are registered, but the BFcache is still not working.
$(window).unbind('beforeunload');
$(window).unbind('unload');
window.onbeforeunload = null;
window.onunload = null;
I also tried:
function UnloadHandler() {
window.removeEventListener('unload', UnloadHandler, false);
}
window.addEventListener('unload', UnloadHandler, false);
$(window).unload(function () { $(window).unbind('unload'); });
but this too does not work.
I have placed some samples online. Remember to test this with Firefox:
this one shows a working BFcache (you will get an different alert based on whether or not the back button was clicked)
http://users.telenet.be/prullen/bfcache/a.html
Loaded piwik, BFCache no longer works
http://users.telenet.be/prullen/bfcache/b.html
Loaded piwik, tried to unset onload event, but still not working
http://users.telenet.be/prullen/bfcache/c.html
Using unloadhandler
http://users.telenet.be/prullen/bfcache/d.html
Suggestions by #roasted
http://users.telenet.be/prullen/bfcache/e.html
http://users.telenet.be/prullen/bfcache/f.html
More information about BFCache:
https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching
You can see another demo of the behavior here:
http://www.twmagic.com/misc/cache.html
If you add dom elements, and click the first link, then return - the dom elements are still there. However, if you add an onload or beforeunload event that is not the case. Again, test this in firefox.
Any ideas?
In order to enable BFCache you need to remove beforeunload event listener. It should be the same listener which was added by Piwik code, otherwise removeEventListener will do nothing.
That listener is unreachable outside of the Piwik's source, so one does not simply remove it.
But, if you have a possibility to insert code before the Piwik, you can try to override addEventListener, track added handlers and expose function to remove all tracked handlers at once.

Categories