32

I'm working on a simple application which is single page based (due to project restrictions) and has dynamic content. I understand the dynamic content alright but what I don't understand is how to set-up a script that changes the html of a div when the hash value in the URL changes.

I need a JavaScript script to work as such:

Url: http://foo.com/foo.html div contents: <h1>Hello World</h1>

Url: http://foo.com/foo.html#foo div contents: <h1>Foo</h1>

How would this work?

Please help! Thanks.

4
  • Have a look at sammy. Commented Feb 20, 2013 at 1:25
  • @Bradchristie ok, i'll take a look but ideally i want to avoid using plugins much... is it possible with just jQuery? Commented Feb 20, 2013 at 1:26
  • Let's look at it realistically. Either you spend the additional time writing something that does what a library does, or you just use the library and move on. You're already using jQuery (a library) because you presumably want the flexibility and not have to write it yourself. Plus sammy lets you insert placeholders and template the incoming hash (very flexible) Commented Feb 20, 2013 at 1:31
  • 1
    @BradChristie, understood, i just need to see an example... im a bit messed up :( Commented Feb 20, 2013 at 1:33

3 Answers 3

77

You can listen to the hashchange event:

$(window).on('hashchange',function(){ 
    $('h1').text(location.hash.slice(1));
});
Sign up to request clarification or add additional context in comments.

4 Comments

ok, this may seem like a stupid question but does this go at the end of the body or in the head because I always get confused in this regard?
@RPM so in the head? Thanks :)
I believe that assumes HTML5's window.onhashchange event exists. this isn't a native event of jquery i don't believe and therefore you're looking at either using a plugin to generate a trigger, or only accept those supporting the fairly new event.
@BradChristie, can you show me an example using the plugin because this isnt working for me :(
5

personally, I'd use sammy which gives you the flexibility to template the hashtag (add placeholders and be able to read them back). e.g.

<script src="/path/to/jquery.js"></script>
<script src="/path/to/sammy.js"></script>
<script>
  $(function(){
      // Use sammy to detect hash changes
      $.sammy(function(){
          // bind to #:page where :page can be some value
          // we're expecting and can be retrieved with this.params
          this.get('#:page',function(){
              // load some page using ajax in to an simple container
              $('#container').load('/partial/'+this.params['page']+'.html');
          });
      }).run();
  });
</script>

<a href="#foo">Load foo.html</a>
<a href="#bar">Load bar.html</a>

An example can be found here: http://jsfiddle.net/KZknm/1/

4 Comments

i've tried: <script> $(function(){ $.sammy(function(){ alert("hello"); }); }); </script> but the script doesnt alert anything when i change the hashtag...
@fermionoid: It doesn't work that way. You need to bind to changes with this.get(...);
@fermionoid: see the example I've included in my updated answer.
sure, ill try this out. It's getting late here so I guess i'll tell you how it goes tomorrow :) thanks for the help. (I've upvoted your answer)
0

Suppose we have list of items, each items has a hash tag as #id

const markup = `
        <li>
            <a class="results__link" href="#${recipe.recipe_id}">
                <figure class="results__fig">
                    <img src="${recipe.image_url}" alt="${limitRecipeTitle(recipe.title)}">
                </figure>
                <div class="results__data">
                    <h4 class="results__name">${recipe.title}</h4>
                    <p class="results__author">${recipe.publisher}</p>
                </div>
            </a>
        </li>
    `;

Now when a user click on any of those list item or reload (http://localhost:8080/#47746) an item with hash tag, hash event will be fired. To recive the fired hash event we must register hash event listener in our app.js

//jquery: 
['hashchange', 'load'].forEach(event => $(window).on(event, controlRecipe));
//js:
['hashchange', 'load'].forEach(event => window.addEventListener(event, controlRecipe));

catch the id in your controlRecipe function

const controlRecipe = async ()=>{
//jq
  const id =  $(window)..location.hash.replace('#','');
//js
  const id = window.location.hash.replace('#','');
  if(id){
    //console.log(id);
    state.recipe = new Recipe(id);
    try {
      await state.recipe.getRecipe();
      state.recipe.calcTime();
      state.recipe.calcServings();
      console.log(state.recipe);
    } catch (error) {
      alert(error);
    }
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.