Parsing Url Hash/Fragment Identifier with JavaScript

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



Leave a reply



Submit