views:

466

answers:

3

I am creating a website with the "anchor navigation" like used with facebook and google mail. I have got it working but not fully. When I load the page with something like #contact it won't load it in unless I click the link for it. Also, would there be a better, more efficient way to do what I am doing? I am not the best person with JS programming.

JavaScript:

$.navigate = function() {
  // a new link
  if($anchor != document.location.hash){
    // add a preloader
    $("#content")
      .empty()
      .html('<p class="align-center"><img src="assets/images/loading.gif" /></p>');
    // change the anchor saved for next time
    $anchor = document.location.hash;
    // get the variables ready for the get
    var i = $anchor.substring(1).split("/");
    var $page = i[0];
    var $y = (i[1]) ? i[1] : false;
    // get the file
    $.get("callback.php", { x: $page, y: $y }, function(data){
      $("#content")
        .empty()
        .html(data);
    },"html");
  }
};

$(function() {

  var $anchor = "";
  // change from the URI. This dont work.
  if(document.location.hash){ $.navigate(); }

  $("a","#nav")
    .css({backgroundColor:"#f7f7f7"})
    .each(function() { 
      $(this).attr("href","#" + $(this).attr("name")); 
    });  

  setInterval('$.navigate()', 300);

});

HTML:

<div id="nav">  
  <ul class="horizontal-nav">
    <li><a href="http://streetmafia.co.uk/" name="index">Home</a></li>
    <li><a href="http://streetmafia.co.uk/about" name="about">About</a></li>
    <li><a href="http://streetmafia.co.uk/portfolio" name="portfolio">Portfolio</a></li>
    <li><a href="http://streetmafia.co.uk/contact" name="contact">Contact</a></li> 
  </ul>
  <div id="l-nav"></div>
  <div id="r-nav"></div>  
</div>
+2  A: 

Try the ReallysimpleHistory jquery plugin.

fserb
+1  A: 

Ditto on the ReallysimpleHistory plugin. I'm not sure I completely understand your code, but I would separate it into 2 functions:

  1. One does the ajax loading (including showing the preloader)
  2. The other one checks the current hash (from the URL) and calls the previous function

In your "$(function() {..." you call the second function first (just once). And then you bind the click event of the links with the first function. You can get the hash in the loading function using $(this).attr('name').

Quick example (not tested :P ):

function ajaxLoad()
{

 var anchor;

 // Check to see if it's being called from an event
 if ( $(this).length > 0 )
 {
   anchor =  $(this).attr('name');  
 }
 else
 {
   anchor = document.location.hash;
 }

}
Januz
A: 

You probably want to check out the jQuery History project: http://www.balupton.com/projects/jquery-history

It is a bit more full featured and easier to implement than others, plus the support if fantastic. There is also a full featured AJAX extension for it, allowing you to easily integrate Ajax requests to your states/hashes to transform your website into a full featured Web 2.0 Application: http://www.balupton.com/projects/jquery-ajaxy

Here is an example of using jQuery History (as taken from the demo site):

// Bind a handler for ALL hash/state changes
$.History.bind(function(state){
    // Update the current element to indicate which state we are now on
    $current.text('Our current state is: ['+state+']');
    // Update the page"s title with our current state on the end
    document.title = document_title + ' | ' + state;
});

// Bind a handler for state: apricots
$.History.bind('/apricots',function(state){
    // Update Menu
    updateMenu(state);
    // Show apricots tab, hide the other tabs
    $tabs.hide();
    $apricots.stop(true,true).fadeIn(200);
});

And an example of jQuery Ajaxy (as taken from the demo site):

        'page': {
            selector: '.ajaxy-page',
            matches: /^\/pages\/?/,
            request: function(){
                // Log what is happening
                window.console.debug('$.Ajaxy.configure.Controllers.page.request', [this,arguments]);
                // Adjust Menu
                $menu.children('.active').removeClass('active');
                // Hide Content
                $content.stop(true,true).fadeOut(400);
                // Return true
                return true;
            },
            response: function(){
                // Prepare
                var Ajaxy = $.Ajaxy; var data = this.State.Response.data; var state = this.state;
                // Log what is happening
                window.console.debug('$.Ajaxy.configure.Controllers.page.response', [this,arguments], data, state);
                // Adjust Menu
                $menu.children(':has(a[href*="'+state+'"])').addClass('active').siblings('.active').removeClass('active');
                // Show Content
                var Action = this;
                $content.html(data.content).fadeIn(400,function(){
                    Action.documentReady($content);
                });
                // Return true
                return true;

And if you ever want to get the querystring params (so yoursite/page.html#page1?a.b=1&a.c=2) you can just use:

$.History.bind(function(state){
    var params = state.queryStringToJSON(); // would give you back {a:{b:1,c:2}}
}

So check out those demo links to see them in action, and for all installation and usage details.

balupton