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.
How to detect change of window hash?
Ben Alman's hashchange jQuery plugin provides the ability to monitor the hash for changes.
How to trigger an event when hash location changes
You should write 'hashchange' instead of 'onhashchange' in your first example.
This code works fine for me, at least in Chrome:
window.addEventListener('hashchange', function(e){
console.log('changed');
})
Here is short code-snippet:
https://jsfiddle.net/bm8jjwmq/
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);
};
}, []);
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.
Example
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+
$watch for location.hash changes
You can specify that in app.config
block using $routeProvider
.
app.config(function ($routeProvider) {
$routeProvider
.when('/home', {
template: 'home.html',
controller: 'homeController'
})
.otherwise('/home');
});
.otherwise
method will redirect the application to /home
, if user tries to access any invalid path which is not specified in config.
Update:
And, If you don't want to use angular routing library you can use native javascript event hashchange
on window to listen for hash change events. and redirect accordingly.
see the below example.
function locationHashChanged() {
if (location.hash !== "#/home") {
console.log('hash is other then #home. will redirect to #home');
console.log('Full path before', document.URL);
window.location.hash = '#/home';
console.log('Full path after', document.URL);
}
}
window.addEventListener('load', locationHashChanged);
window.addEventListener('hashchange', locationHashChanged);
<a href="#home">Home</a>
<br/>
<a href="#somesite">Some-Site</a>
<br/>
<a href="#other">Other</a>
Capture the removal of a hash
Poll window.location.href
to detect changes. Use the change to work out what needs to be reverted. see How can I detect an address bar change with JavaScript?
Related Topics
How to Loop Through a Plain JavaScript Object With the Objects as Members
Async Function Returning Promise, Instead of Value
Formatting a Number With Exactly Two Decimals in JavaScript
Chrome/Firefox Console.Log Always Appends a Line Saying 'Undefined'
Can't Append ≪Script≫ Element
Get the Highlighted/Selected Text
How to Clone an Array of Objects in JavaScript
Is JavaScript Guaranteed to Be Single-Threaded
How to Work Around JavaScript'S Parseint Octal Behavior
Why Does Parseint Yield Nan With Array#Map
Modifying a Copy of a JavaScript Object Is Causing the Original Object to Change
How to Add a Key/Value Pair to a JavaScript Object
Executing ≪Script≫ Elements Inserted With .Innerhtml
What Do Multiple Arrow Functions Mean in JavaScript
How to Check Whether a String Contains a Substring in JavaScript