If you scroll down on this page you will see a black index appear on the left. This is designed using jQuery. First of all we need to understand the blog layout and clarify the rules.
We know that our blog div element is called #blog_message
. Inside this div element there are many H1
, H2
, H3
and HN
elements. Given this rule we can use jQuery to look for and return all the HN
elements we are interested in. For our case we only use H2
and H3
elements as using more will be overkill.
Our index element looks like the following to start off with
<div id='blog_index'>
<ul>
<li tag='top'>Top</li>
</ul>
</div>
Using jquery we will fetch all H2
and H3
and append the results text into a <li>
into our above unorderd list. To get all these elements we use the following code:
//This function creates a list of all items
h2n = 0;
h3n = 0;
$("#message > h2, #message > h3").each(function(i){
//Create the html DOM element in a variable
list = $("<li>" + $(this).text() + "</li>");
//Add the tag attribute and populate it with the current tag type (H2/H3)
list.attr("tag", $(this).prop("tagName"));
//Set the correct n attribute for our tag, and increment the varable hXn by one
if ($(this).prop("tagName") == "H2") { list.attr("n", h2n); h2n++; }
else if ($(this).prop("tagName") == "H3") { list.attr("n", h3n); h3n++; }
//Append our record
$('#blog_index ul').append($(list));
});
the .each(...)
function loops through each H2
and H3
element, and appends the text of the index element into our index list. We then also add attributes such as tag
and n
. Where attribute tag
represents what the element originally was and the attribute n
represents its iteration. We also use hXn++
to add our iteration for each element type, this variable could really be added as an array but for now lets use variables.
If you want nested elements, remove the >
sign from the .each
element selector.
Before we can go any further we need to make our <div id='blog_index'>
to use the position:fixed
property, because scrolling will also scroll our div.
Now that we have a dynamic populated list, we now have to set it to scroll to its correct element. This is where the attribute n
comes in handy, lets look at the code before we go any further:
//The handler for the list clicked objects
$('#blog_index ul li').live('click', function(){
clicked = $(this);
//Scroll to top, If the tag value of the clicked element was "top"
if (clicked.attr("tag") == "top")
{
$('html, body').animate({scrollTop:0}, 'slow');
return true;
}
//Store the pointer to the original element that the index represents
//Printed out this should spell "#message H2:eq(4)"
goto_ele = $("#message " + clicked.attr("tag") + ":eq(" + clicked.attr("n") + ")");
//Scroll to the right element
$('html, body')
.stop(true,true)
.animate(
{
//Go to the called elements top position
scrollTop: goto_ele.offset().top
},
'fast'
);
return true;
});
The above code handlers the top
function differently to the element function. If the tag
attribute of the clicked element is equal to top
then we just scroll our window to the top, otherwise:
We store the referencing element into the goto_ele
, this variable should be interpreted like the following for 3rd H2 of the message
#message H2:eq(3)
The :eq(n)
refrences the nth element type. Once we know which element we are scrolling to we simply use the .offset().top
call in jQuery as a reference to scrollTo:
in animate
Note we use the live
event handler as we want each element appended to have this handler. If we use click
there will be no handler for the new appended elements. Make sure you read up on live
handlers to understand why we use this in more detail
<div id='blog_index'>
<ul>
<li tag='top'>Top</li>
</ul>
</div>
<div id='message'>
<h2>Hello Ladies and Gentlemen</h2>
<p>....</p>
<h3>Im Back!</h3>
<p>Cheers!</p>
</div>
Hope this helps.