Parsing URL hash/fragment identifier with JavaScript
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!)
Parse URL # fragment with javascript
Use jQuery BBQ, which is a battle-tested library that handles state management.
$(window).on('hashchange', function(e) { // event fired when the fragment changes
var frag = $.deparam.fragment();
});
It also makes adding or changing the fragment easy:
$.bbq.pushState({ someParam: 'value' });
How do I get the fragment identifier (value after hash #) from a URL?
No need for jQuery
var type = window.location.hash.substr(1);
Since String.prototype.substr
is deprecated use substring
instead.
var type = window.location.hash.substring(1);
How can you check for a #hash in a URL using JavaScript?
Simple use of location hash:
if(window.location.hash) {
// Fragment exists
} else {
// Fragment doesn't exist
}
Retrieve the fragment (hash) from a URL and inject the values into the bean
You can do this with help of window.onhashchange
which fills an input field of a hidden form which submits itself asynchronously when the input field has changed.
Here's a kickoff example of the Facelets page:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>SO question 3475076</title>
<script>
window.onload = window.onhashchange = function() {
var fragment = document.getElementById("processFragment:fragment");
fragment.value = window.location.hash;
fragment.onchange();
}
</script>
<style>.hide { display: none; }</style>
</h:head>
<h:body>
<h:form id="processFragment" class="hide">
<h:inputText id="fragment" value="#{bean.fragment}">
<f:ajax event="change" execute="@form" listener="#{bean.processFragment}" render=":showFragment" />
</h:inputText>
</h:form>
<p>Change the fragment in the URL. Either manually or by those links:
<a href="#foo">foo</a>, <a href="#bar">bar</a>, <a href="#baz">baz</a>
</p>
<p>Fragment is currently: <h:outputText id="showFragment" value="#{bean.fragment}" /></p>
</h:body>
</html>
Here's how the appropriate bean look like:
package com.stackoverflow.q3475076;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.event.AjaxBehaviorEvent;
@ManagedBean
@RequestScoped
public class Bean {
private String fragment;
public void processFragment(AjaxBehaviorEvent event) {
// Do your thing here. This example is just printing to stdout.
System.out.println("Process fragment: " + fragment);
}
public String getFragment() {
return fragment;
}
public void setFragment(String fragment) {
this.fragment = fragment;
}
}
That's all.
Note that the onhashchange
event is relatively new and not supported by the older browsers. In absence of the browser support (undefinied and so on), you'd like to check window.location.hash
at intervals using setInterval()
instead. The above code example should at least give a good kickoff. It works at at least FF3.6 and IE8.
Related Topics
How to Pass Parameters to a Script Tag
Validate That a String Is a Positive Integer
Jasmine: Async Callback Was Not Invoked Within Timeout Specified by Jasmine.Default_Timeout_Interval
JavaScript If Statements Not Working
Check Whether an Array Exists in an Array of Arrays
What Is {This.Props.Children} and When You Should Use It
How to Get a JavaScript Object Property Name That Starts with a Number
Extending Built-In Natives in Es6 with Babel
JavaScript Getelementbyid() Not Working
How to Check If an Element Is Overlapping Other Elements
Is There Any Difference Between Declared and Defined Variable
Leaflet Drawing Tiles Disjointly
JavaScript - Are Dom Redraw Methods Synchronous
How to Access Component Methods from "Outside" in Reactjs
How to Check If the Url Contains a Given String
Regex Created via New Regexp(Mystring) Not Working (Backslashes)
Node.Js Tail-Call Optimization: Possible or Not
Event Delegation VS Direct Binding When Adding Complex Elements to a Page