How to detect if URL has changed after hash in JavaScript
In modern browsers (IE8+, FF3.6+, Chrome), you can just listen to the hashchange
event on window
.
In some old browsers, you need a timer that continually checks location.hash
. If you're using jQuery, there is a plugin that does exactly that.
Below I undo any URL change, to keep just the scrolling:
<script type="text/javascript">
if (window.history) {
var myOldUrl = window.location.href;
window.addEventListener('hashchange', function(){
window.history.pushState({}, null, myOldUrl);
});
}
</script>
Note that above used
history
-API is available in Chrome, Safari, Firefox 4+, and Internet Explorer 10pp4+
How to detect URL changes in SPA
Under normal circumstances, there isn't an event when the URL changes. You are loading a new document (although you have load
and so on)
If you are setting a new URL with JavaScript (i.e. with pushState
) then there isn't an event, but you don't need one because you're already explicitly writing code around it, so you just add whatever else you need to that code.
You'll get a popstate
event if the URL changes back though your pushState history via the browser back button or similar.
Consequently, there is no good generic way to hook into every SPA. The closest you could come would be to use setInterval
and inspect the value of location.href
to see if it changed since the last inspection.
Detect an URL change in a SPA
This https://stackoverflow.com/a/41825103/7042552 did the job for me, unbelievable we still have to use these hacks in 2018.
How to detect change in the URL hash in Next.js?
You can listen to hash changes using hashChangeStart
event from router.events
.
const Test = () => {
const router = useRouter();
useEffect(() => {
const onHashChangeStart = (url) => {
console.log(`Path changing to ${url}`);
};
router.events.on("hashChangeStart", onHashChangeStart);
return () => {
router.events.off("hashChangeStart", onHashChangeStart);
};
}, [router.events]);
return (
<>
<Link href="/#some-hash">
<a>Link to #some-hash</a>
</Link>
<Link href="/#some-other-hash">
<a>Link to #some-other-hash</a>
</Link>
</>
);
};
If you're not using next/link
or next/router
for client-side navigation (not recommended in Next.js apps), then you'll need to listen to the window
's hashchange
event.
Your useEffect
would look like the following.
useEffect(() => {
const onHashChanged = () => {
console.log('Hash changed');
};
window.addEventListener("hashchange", onHashChanged);
return () => {
window.removeEventListener("hashchange", onHashChanged);
};
}, []);
Detect specific part of url change
Do it with jQuery, works fine for me.
$(window).on("hashchange", function(){
alert('change');
});
Tested whith mySite.fr/#toto and mySite.fr/#tototata
Event was fired when anchor changed.
How can I detect changes in location hash?
The only way to really do this (and is how the 'reallysimplehistory' does this), is by setting an interval that keeps checking the current hash, and comparing it against what it was before, we do this and let subscribers subscribe to a changed event that we fire if the hash changes.. its not perfect but browsers really don't support this event natively.
Update to keep this answer fresh:
If you are using jQuery (which today should be somewhat foundational for most) then a nice solution is to use the abstraction that jQuery gives you by using its events system to listen to hashchange events on the window object.
$(window).on('hashchange', function() {
//.. work ..
});
The nice thing here is you can write code that doesn't need to even worry about hashchange support, however you DO need to do some magic, in form of a somewhat lesser known jQuery feature jQuery special events.
With this feature you essentially get to run some setup code for any event, the first time somebody attempts to use the event in any way (such as binding to the event).
In this setup code you can check for native browser support and if the browser doesn't natively implement this, you can setup a single timer to poll for changes, and trigger the jQuery event.
This completely unbinds your code from needing to understand this support problem, the implementation of a special event of this kind is trivial (to get a simple 98% working version), but why do that when somebody else has already.
Detect changes on the url
You need to store the URL when the page loads as a starting point and setInterval
to check for changes and modify based on that.
The following code does this check twice a second (500ms):
// store url on load
let currentPage = location.href;
// listen for changes
setInterval(function()
{
if (currentPage != location.href)
{
// page has changed, set new page as 'current'
currentPage = location.href;
// do your thing..
}
}, 500);
Related Topics
Javascript Function Not Defined Error (But It Is Defined)
Wait for Http Request in Angular
Random Numbers Between 1 and 50; 50 Times
How to Open a File/Browse Dialog Using JavaScript
How to Replace Double/Multiple Slash to Single in Url
How to Find Middle Element of Array in JavaScript
How to Enable Scrolling on Website That Disabled Scrolling
Refresh Page and Keep Scroll Position
Safari: Focus Event Doesn't Work on Button Element
How to Get the Value by a Key from a Super Nested Json
Regex to Replace Everything Except Numbers and a Decimal Point
Regex to Remove Certain Characters At the Beginning and End of a String
Get Directory of a File Name in JavaScript
Show Virtual Keyboard on Mobile Phones in JavaScript
How to Clear Input After Onclick With Reactjs
Websocket Connection Failed: Error During Websocket Handshake: Unexpected Response Code: 400
How to Get a Div Element from an External Webpage in HTML File