Reputation: 183999
Looking for a way to parse key pairs out of the hash/fragment of a URL into an object/associative array with JavaScript/JQuery
Upvotes: 58
Views: 78791
Reputation: 1124
Use URLSearchParams. It's fully supported in major browsers and server-side JavaScript runtimes that implement WHATWG URL Standard. Browser coverage: https://caniuse.com/urlsearchparams.
Read a key from the current URL (assuming you are running on a browser UA):
// window.location.hash = "#any_hash_key=any_value"
const parsedHash = new URLSearchParams(
window.location.hash.substring(1) // any_hash_key=any_value
);
console.log(parsedHash.get("any_hash_key")); // any_value
Read a key from an arbitrary URL (make sure to check for exceptions that may be thrown by URL constructor when given URL is not valid):
const url = new URL("https://example.com#foo=bar&baz=qux&val=val+has+spaces");
const parsedHash = new URLSearchParams(
url.hash.substring(1) // foo=bar&baz=qux&val=val+has+spaces
);
console.log(parsedHash.get("baz")); // qux
console.log(parsedHash.get("val")); // val has spaces
Check out the Mozilla docs I linked above to see all of the methods of the interface.
Upvotes: 56
Reputation: 183999
Here it is, modified from this query string parser:
function getHashParams() {
var hashParams = {};
var e,
a = /\+/g, // Regex for replacing addition symbol with a space
r = /([^&;=]+)=?([^&;]*)/g,
d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
q = window.location.hash.substring(1);
while (e = r.exec(q))
hashParams[d(e[1])] = d(e[2]);
return hashParams;
}
No JQuery/plug-in required
Update:
I'm now recommending the jQuery BBQ plugin as per Hovis's answer. It covers all hash parsing issues.
Update (2019)
Apparently there is now a URLSearchParams function - see answer from @Berkant
Upvotes: 54
Reputation: 15875
Do this in pure Javascript:
var hash = window.location.hash.substr(1);
var result = hash.split('&').reduce(function (result, item) {
var parts = item.split('=');
result[parts[0]] = parts[1];
return result;
}, {});
http://example.com/#from=2012-01-05&to=2013-01-01
becomes
{from: '2012-01-05', to:'2013-01-01'}
Upvotes: 22
Reputation: 1022
I was looking through a bunch of answers for this problem and wound up cobbling them together using one line with reduce
:
const hashObj = location.hash.replace('#', '').split('&').reduce((prev, item) => Object.assign({[item.split('=')[0]]: item.split('=')[1]}, prev), {});
There's obviously a lot going on in that one line. It can be rewritten like this for clariry:
const hashObj = location.hash.replace('#', '').split('&').reduce((prev, item) => {
return Object.assign({[item.split('=')[0]]: item.split('=')[1]}, prev);
}, {});
Upvotes: 2
Reputation: 486
This jquery API does parse hash tags: https://jhash.codeplex.com/
// get the "name" querystring value
var n = jHash.val('name');
// get the "location" querystring value
var l = jHash.val('location');
// set some querystring values
jHash.val({
name: 'Chris',
location: 'WI'
});
Upvotes: 0
Reputation: 4185
You can also use the .hash property, demonstrated in this scrolling table of contents example for a clicked link or for the locatioin.
Upvotes: 0
Reputation: 16870
You might want to check out jsuri. It seems to work well for me.
Upvotes: -3
Reputation: 265228
My answer to this question should do what you're looking for:
url_args_decode = function (url) {
var args_enc, el, i, nameval, ret;
ret = {};
// use the DOM to parse the URL via an 'a' element
el = document.createElement("a");
el.href = url;
// strip off initial ? on search and split
args_enc = el.search.substring(1).split('&');
for (i = 0; i < args_enc.length; i++) {
// convert + into space, split on =, and then decode
args_enc[i].replace(/\+/g, ' ');
nameval = args_enc[i].split('=', 2);
ret[decodeURIComponent(nameval[0])]=decodeURIComponent(nameval[1]);
}
return ret;
};
Upvotes: 0
Reputation: 889
Check out: jQuery BBQ
jQuery BBQ is designed for parsing things from the url (query string or fragment), and goes a bit farther to simplify fragment-based history. This is the jQuery plugin Yarin was looking for before he put together a pure js solution. Specifically, the deparam.fragment() function does the job. Have a look!
(The support site I'm working on uses an asynchronous search, and because BBQ makes it trivial to tuck entire objects into the fragment I use it to 'persist' my search parameters. This gives my users history states for their searches, and also allows them to bookmark useful searches. Best of all, when QA finds a search defect they can link straight to the problematic results!)
Upvotes: 29