jQuery Plugin: Table of Contents with Smooth Scrolling

Posted in Coding, JS & AJAX • Posted on 39 Comments

Hey guys, have you noticed that pretty box on WordPress codex that gives us a preview about what we can see on a page? So, I haven’t seen too many blogs use this kind of feature and it is really useful for our readers, since they can just skip to the content that they are interested in and avoid wasting time. Wikipedia has a table of contents that makes it easier for readers to skip around, right?

I’m not the very first to do something like this with jQuery. But our goal in here is to develop a complete jQuery plugin, from start to finish, with options, and that is easy to customize. And, of course, something that I hope is useful to you

So, let’s rock!

STOC – Smooth Table of Contents jQuery plugin

Since there are a lot of “tocs” around the web, our plugin will be called STOC and the main features are:

  • Automatically adds the table of contents to target element
  • You can select to search just a part of you page
  • You can select what is the first heading we will have to search (h1, h2…)
  • You can select the “depth” of the search
  • SubItems are made of sublists inside parent item
  • You can select which text will display before the table (title)
  • You can select whether ol or ul to you listing
  • You can enable / disable smooth scrolling

Here is how it should look in our demo:

Here’s a running Demo. You can also download all files here.

Planning and planning – Before code, let’s think about it

The main idea is to have a jQuery plugin that generates a table of content inside the target element. To have this working we need some basic customization with these options:

  • Where to search – If the table is generated based on entire page, just a section content
  • Depth of H’s – How many “levels” of titles we will have in our search
  • Start tag – Which level of heading will be the first on set (h1, h2, h3)
  • Title if the box – What to display as box’s title
  • List type – whether to have ordered or unordered list

The hardest thing when we are doing something just for fun is to define the scope. Actually it is hard too when we have a “real” project, but when it comes to pet projects it is harder because you just can’t measure accurately what will bring you the expected revenue (fun).

So, what do I do in these cases is list anything that I could do on it, and just cut down what will take too much time and will not be so good to do.

In this case, for example I listed these features:

  • Customizable via options – I think this one was essential, so I just kept it
  • Smooth scrolling - This one I didn’t see in any other plugin / snippet. It would be good to have, so I kept it.
  • Accordion for hierarchy - I found this idea really cool, but useless, I drop it.
  • Preview of the text on hover - I’ve stolen this idea of one site but actually didn’t find it useful also, so I drop it.

So what I’ve done here is to define which of the cool features had big potential to be a waste of time. Even if I had more time to code I would never use them, just because they haven’t the expected benefit (fun x time).

Now that we now what we want to do, let’s start to code.

Basic plugin structure with options

First we need to create our file. The standard for jQuery plugins files names is jQuery.PLUGINNAME.js so, our file will be jquery.stoc.js.

We also have all our options defined above, so we need now to save a variable for each one of them, so our user can send his own parameters.

Here is our commented code:

/*
This line creates our function "wrapped" by jQuery container, so we won't have any problem with others libraries
*/
(function($){
/*
Here the standard is $.fn.PLUGINNAME. so when we call $(element).stoc() jquery will run this code
Pay attention that we pass options to our funcion, so when user defines it we can extend our plugin
*/
	$.fn.stoc = function(options) {
	//Our default options
	var defaults = {
		search: "body", //where we will search for titles
		depth: 6, //how many hN should we search
		start: 1, //which hN will be the first (and after it we go just deeper)
		stocTitle: "<h2>Contents</h2>", //what to display before our box
		listType: "ul", //could be ul or ol
		smoothScroll: 1
	};

	//let's extend our plugin with default or user options when defined
	var options = $.extend(defaults, options);

	return this.each(function() {
		//our functions here
		alert("I'm a beta tester alert box!");
	});
};
})(jQuery);

Let’s try a simple demo to see it working. Create this HTML in same folder as our plugin:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>Smooth Table Of Contents jQuery plugin - DEMO</title>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
	<script type="text/javascript" src="jquery.stoc.js"></script>
	<script type="text/javascript">
		$(function(){
			$("#items").stoc();
		});
	</script>
	<style type="text/css">
		body {
			background: #fafafa url(handmadepaper.png); //via subtlepatterns
		}
			#container {
				position: relative;
				top: 50px;
				width: 960px;
				margin: 0 auto;
				padding-bottom: 20px;
			}
			#container p, #container h1, #container h2, #container h3, #container h4, #container h5 {
				font-family: "arial";
				padding: 10px 20px 0;
				margin: 0
			}
			#items {
				float: right;
				width: 260px;
				padding-bottom: 10px;
				margin:0 0 10px 20px;
				/* rgba with ie compatibility */
				background-color: transparent;
				background-color: rgba(255,255,255,0.4);
				filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#20ffffff,endColorstr=#20ffffff);
				-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#20ffffff,endColorstr=#20ffffff)";
			}
				#items ul {
					margin: 0 0 0 20px;
					padding: 0 0 5px;
					list-style-type: none;
				}
					#items ul ul {
						font-size: 90%;
					}
				#items ul a {
					font-family: "arial";
					text-decoration: none;
					color: #c10000;
				}
					#items ul a:hover { color: #ff0000 }
	</style>
</head>
<body id="page-1">
	<div id="container">
		<div id="items">
		</div>
		<h1>1 - Phasellus vulputate</h1>
		<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas metus est, egestas vel aliquet at, pellentesque nec lorem. Pellentesque molestie bibendum eros, eu suscipit nisi volutpat fringilla. Vivamus fringilla nisl ut ante commodo porta. Morbi ipsum nunc, sollicitudin ac pretium pretium, iaculis vel enim. Nulla cursus porta orci, sed vulputate magna feugiat et. Aliquam nibh massa, pharetra tincidunt vehicula ac, pellentesque vitae nibh. In lobortis semper eros fermentum pretium. Sed posuere, urna eget ornare luctus, mi lectus lacinia leo, sit amet faucibus orci ipsum sit amet ipsum. Maecenas sapien neque, ultrices a lacinia sit amet, fermentum non enim. Integer at venenatis orci. In hac habitasse platea dictumst.</p>
		[... lot of more lipsum text with h's here]
	</div>
</body>
</html>

If you create this file, when you load it you should see our pretty beta tester alert. So our plugin is being called (make sure that you add jquery before it, as I’ve done including api.googleapis…). if you want to overwrite any option defined before, you just have to pass it as .stoc({ OPTIONNAME: VALUE }) instead of just .stoc(). For example, to define our search just in #container, add .stoc({ search: "#container" }).

How should we select our headings?

Now we have to prepare our plugin to get all h’s that we have to (based in our options). What we can do is get all the headings we have to, and when we loop through each one of them we will discover which level it is. I think it is easier than trying to get the whole hierarchy for each “tree” of headings.

Since our current object can change as we run our code, we have also to “cache” our current object so we will always now which object we are modifying. Our code now will be:

   return this.each(function() {
		//"cache" our target and search objects
		obj = $(this); //target
		src = $(options.search); //search
		//let's declare some variables. We need this var declaration to create them as local variables (not global)
		var appHTML = "", tagNumber = 0, txt = "", id = "", before = "", after = "", previous = options.start, start = options.start, depth = options.depth, i = 0, srcTags = "h" + options.start, cacheHN = "";

		//which tags we will search
		while ( depth > 1) {
			start++; //we will just get our start level and numbers higher than it
			srcTags = srcTags + ", h" + start;
			depth--; //since went one level up, our depth will go one level down
		}

    });

If you alert you srcTags you will see something like this “h1, h2, h3, h4, h5, h6″. This is what we will pass to jQuery as the elements that we want to search for.

Building our table

We have all our elements, what we have to do is run a function on each one of them with the wonderful each() jQuery function.

Inside each element, we need to:

  • Know which level the current element is (tagNumber)
  • Set one id to this element, if it doesn’t have one
  • Get the elements text
  • Test if is its level is lower, higher or equal than previous element and open / close ul’s based on this
    • If element number is higher than previous means that we went down one level (e.g. from h2 to h3)
    • If element number is equals to previous means that we stay on same level (e.g. h4)
    • If element number is lower than previous means that we went up, but we don’t know how many levels (e.g. from h4 to h1)
  • Append element HTML to our target item

We also have to correct the last item because if it is not top-level it will let some uls open, and we don’t want it :D

Our commented code now will be:

/* our setup stuff here */
/*inside our return function */
	//which tags we will search
		while ( depth > 1) {
			start++; //we will just get our start level and numbers higher than it
			srcTags = srcTags + ", h" + start;
			depth--; //since went one level up, our depth will go one level down
		}
		src.find(srcTags).each(function() {
			//we will cache our current H element
			cacheHN = $(this);
			//if we are on h1, 2, 3...
			tagNumber = ( cacheHN.get(0).tagName ).substr(1);

			//sets the needed id to the element
			id = cacheHN.attr('id');
			if (id == "") { //if it doesn't have only, of course
				id = "h" + tagNumber + "_" + i;
				cacheHN.attr('id', id);
			}
			//our current text
			txt = cacheHN.text();

			switch(true) { //with switch(true) we can do comparisons in each case
				case (tagNumber > previous) : //it means that we went down one level (e.g. from h2 to h3)
						appHTML = appHTML + "<" + options.listType +"><li>"+ before +"<a href=\"#"+ id + "\">" + txt + "</a>";
						previous = tagNumber;
					break;
				case (tagNumber == previous) : //it means that stay on the same level (e.g. h3 and stay on it)
						appHTML = appHTML + "</li><li>"+ before +"<a href=\"#"+ id + "\">" + txt +  "</a>";
					break;
				case (tagNumber < previous) : //it means that we went up but we don't know how much levels  (e.g. from h3 to h2)
						while(tagNumber != previous) {
							appHTML = appHTML + "</" + options.listType +"></li>";
							previous--;
						}
						appHTML = appHTML + "<li>"+ before +"<a href=\"#"+ id + "\">" + txt + "</a></li>";
					break;
			}
			i++;
		});
		//corrects our last item, because it may have some opened ul's
		while(tagNumber != options.start) {
			appHTML = appHTML + "</" + options.listType +">";
			tagNumber--;
		}
		//append our html to our object
		appHTML = options.stocTitle + "<"+ options.listType + ">" + appHTML + "</" + options.listType + ">";
		obj.append(appHTML);

How to Make our STOC smoother

I’ve stolen CSS trick’s smooth scroll code, but I hope they don’t mind :D

What we have to do here is just put this (compressed) function to load when our smooth scroll in on (if the user doesn’t set it as 0).

/*all code above in here*/
	//append our html to our object
		appHTML = options.stocTitle + "<"+ options.listType + ">" + appHTML + "</" + options.listType + ">";
		obj.append(appHTML);

		//our pretty smooth scrolling here
		// acctually I've just compressed the code so you guys will think that I'm the man . Source: http://css-tricks.com/snippets/jquery/smooth-scrolling/
		if (options.smoothScroll == 1) {
			$(window).load(function(){
				function filterPath(string){return string.replace(/^\//,'').replace(/(index|default).[a-zA-Z]{3,4}$/,'').replace(/\/$/,'')}var locationPath=filterPath(location.pathname);var scrollElem=scrollableElement('html','body');obj.find('a[href*=#]').each(function(){var thisPath=filterPath(this.pathname)||locationPath;if(locationPath==thisPath&&(location.hostname==this.hostname||!this.hostname)&&this.hash.replace(/#/,'')){var $target=$(this.hash),target=this.hash;if(target){var targetOffset=$target.offset().top;$(this).click(function(event){event.preventDefault();$(scrollElem).animate({scrollTop:targetOffset},400,function(){location.hash=target})})}}});function scrollableElement(els){for(var i=0,argLength=arguments.length;i<argLength;i++){var el=arguments[i],$scrollElement=$(el);if($scrollElement.scrollTop()>0){return el}else{$scrollElement.scrollTop(1);var isScrollable=$scrollElement.scrollTop()>0;$scrollElement.scrollTop(0);if(isScrollable){return el}}}return[]}
			});
		}

Our final result is this:

(function($){
 $.fn.stoc = function(options) {
	//Our default options
	var defaults = {
		search: "body", //where we will search for titles
		depth: 6, //how many hN should we search
		start: 1, //which hN will be the first (and after it we go just deeper)
		stocTitle: "<h2>Contents</h2>", //what to display before our box
		listType: "ul", //could be ul or ol
		smoothScroll: 1
	};

	//let's extend our plugin with default or user options when defined
	var options = $.extend(defaults, options);

    return this.each(function() {
		//"cache" our target and search objects
		obj = $(this); //target
		src = $(options.search); //search
		//let's declare some variables. We need this var declaration to create them as local variables (not global)
		var appHTML = "", tagNumber = 0, txt = "", id = "", before = "", after = "", previous = options.start, start = options.start, depth = options.depth, i = 0, srcTags = "h" + options.start, cacheHN = "";

		//which tags we will search
		while ( depth > 1) {
			start++; //we will just get our start level and numbers higher than it
			srcTags = srcTags + ", h" + start;
			depth--; //since went one level up, our depth will go one level down
		}
		src.find(srcTags).each(function() {
			//we will cache our current H element
			cacheHN = $(this);
			//if we are on h1, 2, 3...
			tagNumber = ( cacheHN.get(0).tagName ).substr(1);

			//sets the needed id to the element
			id = cacheHN.attr('id');
			if (id == "") { //if it doesn't have only, of course
				id = "h" + tagNumber + "_" + i;
				cacheHN.attr('id', id);
			}
			//our current text
			txt = cacheHN.text();

			switch(true) { //with switch(true) we can do comparisons in each case
				case (tagNumber > previous) : //it means that we went down one level (e.g. from h2 to h3)
						appHTML = appHTML + "<" + options.listType +"><li>"+ before +"<a href=\"#"+ id + "\">" + txt + "</a>";
						previous = tagNumber;
					break;
				case (tagNumber == previous) : //it means that stay on the same level (e.g. h3 and stay on it)
						appHTML = appHTML + "</li><li>"+ before +"<a href=\"#"+ id + "\">" + txt +  "</a>";
					break;
				case (tagNumber < previous) : //it means that we went up but we don't know how much levels  (e.g. from h3 to h2)
						while(tagNumber != previous) {
							appHTML = appHTML + "</" + options.listType +"></li>";
							previous--;
						}
						appHTML = appHTML + "<li>"+ before +"<a href=\"#"+ id + "\">" + txt + "</a></li>";
					break;
			}
			i++;
		});
		//corrects our last item, because it may have some opened ul's
		while(tagNumber != options.start) {
			appHTML = appHTML + "</" + options.listType +">";
			tagNumber--;
		}
		//append our html to our object
		appHTML = options.stocTitle + "<"+ options.listType + ">" + appHTML + "</" + options.listType + ">";
		obj.append(appHTML);

		//our pretty smooth scrolling here
		// acctually I've just compressed the code so you guys will think that I'm the man . Source: http://css-tricks.com/snippets/jquery/smooth-scrolling/
		if (options.smoothScroll == 1) {
			$(window).load(function(){
				function filterPath(string){return string.replace(/^\//,'').replace(/(index|default).[a-zA-Z]{3,4}$/,'').replace(/\/$/,'')}var locationPath=filterPath(location.pathname);var scrollElem=scrollableElement('html','body');obj.find('a[href*=#]').each(function(){var thisPath=filterPath(this.pathname)||locationPath;if(locationPath==thisPath&&(location.hostname==this.hostname||!this.hostname)&&this.hash.replace(/#/,'')){var $target=$(this.hash),target=this.hash;if(target){var targetOffset=$target.offset().top;$(this).click(function(event){event.preventDefault();$(scrollElem).animate({scrollTop:targetOffset},400,function(){location.hash=target})})}}});function scrollableElement(els){for(var i=0,argLength=arguments.length;i<argLength;i++){var el=arguments[i],$scrollElement=$(el);if($scrollElement.scrollTop()>0){return el}else{$scrollElement.scrollTop(1);var isScrollable=$scrollElement.scrollTop()>0;$scrollElement.scrollTop(0);if(isScrollable){return el}}}return[]}
			});
		}
    });
 };
})(jQuery);

Are you hungry yet?

What about you help me with some improvements on this plugin? Do you have any tip? Anything that you can think of a better way to do?

Do you have any other features in mind? Or even another plugin idea that you’d like to see a tutorial on?

Share your thoughts with us! :D

43 Written ArticlesWebsiteGoogle+

I'm a web designer and entrepreneur from Itajubá (MG), Brasil. I love writing about obscure topics and doing some cool stuff. And also I do some FREE stuff, check it out: http://www.roch.com.br/

39 Comments Best Comments First
  • Rochester Oliveira

    Tuesday, June 7th, 2011 05:52

    12

    Hey Nanang, I think it is pretty useful too. Hope you find much more useful content here, on 1WD!

    []’s

    0
  • Yachika Verma

    Tuesday, June 7th, 2011 14:51

    14

    It seems very good, I liked it!

    0
    • Rochester Oliveira

      Tuesday, June 7th, 2011 15:00

      16

      Hi Yachika,

      I’m glad you liked it! This is why we all write :D

      []’s

      0
  • Rochester Oliveira

    Tuesday, June 7th, 2011 14:59

    15

    Thank you Incircle media!

    Don’t forget to check out our older articles, they are great too :D

    0
  • egiova

    Saturday, June 11th, 2011 18:17

    17

    Thanks for sharing, it’s a very useful technique. I just want to add that a scroll to top will be a nice feature. But there’s so many options to implement this… it’s not a problem.

    I spent several years making internal manuals in various companies, and online classes too, it’s like making a mini-site with huge individual pages. I found that a non-fix vertical menu on a left sidebar was the more practical and intuitive way to implement a table of content. You want your reader focused on its reading, so the wiki format isn’t, in my feel, the best way to help somebody to learn and memorize something new. If you sum to this some tool-tips and modal windows, and your table of content, you have a fantastic and powerful tool for teaching.
    Once again, thanks for sharing this.

    0
    • Rochester Oliveira

      Sunday, June 12th, 2011 06:03

      18

      Hey egiova,

      As Abdelhadi said below it would be really helpful. It is pretty easy to add it, is just append some code (like this “top” link) while you are in each() loop.

      I agree with you, this must to be the best way to wiki-like sites, and I think it is really helpful for tutorials or roundups, so readers can go and read just what they want to learn (like if you are in a jquery plugins roundup and just want to see the sliders)..

      Thank you, again!
      []’s

      0
  • Rochester Oliveira

    Tuesday, June 7th, 2011 05:50

    11

    You are welcome enrusa :D

    []’s

    0
  • Rochester Oliveira

    Sunday, August 7th, 2011 05:02

    19

    Hi Arun,
    That’s why I’m here!

    Thank you!
    []’s

    0
  • wesley

    Monday, June 6th, 2011 18:20

    5

    Under what license is this file released? MIT?

    Thanks! Great stuff.

    0
    • Rochester Oliveira

      Monday, June 6th, 2011 19:41

      6

      Hey wesley, I think we missed it. MIT is ok to me, since you can do anything you want with this code and it has no warranty.

      Thank you for pointing it out, next time I’ll include this in our .zip !

      []’s

      0
  • Julian

    Monday, June 6th, 2011 16:46

    10

    nice code,and good description to develop own jquery plugins. very
    usefull, thanks!

    0
    • Rochester Oliveira

      Monday, June 6th, 2011 19:42

      7

      Hey Julian, thank you!

      I’m glad you liked it, this is the reason we write this stuff :D

      []’s

      0
  • Maicon Sobczak

    Monday, June 6th, 2011 20:27

    9

    Is always helpful have the opportunity to learn how a plugin is estructured.

    0
    • Rochester Oliveira

      Tuesday, June 7th, 2011 05:53

      13

      Hey Maicon, did you notice how simple it is? I mean, with a few lines you can have a plugin, this is pretty cool, and jQuery is awsome!

      []’s

      0
  • Abdelhadi Touil

    Monday, June 6th, 2011 14:10

    8

    Very nice plugin; thanks very much for sharing.
    I think it’ll be better if it adds automatically a “top” link ine the of each section. What do you think?
    (Sorry for my bad English)

    0
    • Rochester Oliveira

      Monday, June 6th, 2011 16:34

      3

      Hey Abdelhadi, It is a good idea, and pretty simple do do, since our smooth scrolling can apply to this link also..

      Thank you for the insight!
      []’s

      0
  • Alex C

    Monday, August 22nd, 2011 10:24

    20

    Amazing stuff! Thanks for sharing this. I was looking to add this to a SharePoint publishing page and thought of creating from scratch until I came across this. Very nice. Thank you for creating this :)

    0
    • Rochester Oliveira

      Monday, August 22nd, 2011 14:24

      22

      Hi Alex, thank you!

      I’m glad you liked it
      []’s

      0
  • Hasan

    Monday, June 6th, 2011 12:16

    1

    it might be very good if we see a little demo for this script

    0
    • Hasan

      Monday, June 6th, 2011 12:18

      2

      Sorry ive missed it out. I ve seen it. Very nice! Thanks! :)

      0
      • Rochester Oliveira

        Monday, June 6th, 2011 16:35

        4

        Hey Hassan, don’t worry about it :D I do this all the time.. :)

        Thank you!

        []’s

        0
  • Sherwin Hermogenes

    Thursday, January 19th, 2012 19:13

    34

    Great plugin the effect is really very smooth.

    0
    • Rochester Oliveira

      Monday, January 30th, 2012 02:30

      37

      Cool, isn’t it, Sherwin?

      Thanks ;)

      0
  • goldsky

    Saturday, January 28th, 2012 14:26

    35

    Hello Roch,
    I edited your code here:
    1. fixed by omitting the last closing li, because after the first loop, the li closed its ul descendant.
    2. added beforeText and afterText

    cheers.

    0
    • Rochester Oliveira

      Monday, January 30th, 2012 02:30

      36

      Hey goldsky,

      I’m really glad you liked it so much to work on improvements.. Thanks a lot!

      []’s

      0
  • RynoRn

    Thursday, May 17th, 2012 11:22

    38

    Hey,

    I fixed a bug in your plugin where it went to an infinite loop at this line:

    while(tagNumber != options.start) {
    appHTML = appHTML + “”;
    tagNumber–;
    }

    The tagnumber went under 0 so this loop never stopped and made the browsers to crash. You can find the fix here:
    https://gist.github.com/2719592

    0
    • Dainis Graveris

      Friday, May 18th, 2012 03:14

      39

      Hello RynoRn, oh my apologies – thank you for fixing it!

      0
  • Diego

    Friday, October 28th, 2011 15:46

    31

    sorry.
    Here is the code

    case (tagNumber < previous) : //it means that we went up but we don't know how much levels (e.g. from h3 to h2)
    appHTML = appHTML + "";
    while(tagNumber != previous) {
    appHTML = appHTML + "";
    previous--;
    }
    appHTML = appHTML + ""+ before +"" + txt + "";
    break;

    0
    • Diego

      Friday, October 28th, 2011 15:48

      32

      Here i go again…

      case (tagNumber < previous) : //it means that we went up but we don't know how much levels (e.g. from h3 to h2)
      appHTML = appHTML + "”;
      while(tagNumber != previous) {
      appHTML = appHTML + “”;
      previous–;
      }
      appHTML = appHTML + “”+ before +”lessThan a h ref=\”#”+ id + “\”>” + txt + “Lessthan/a>”;
      break;

      0
      • Rochester Oliveira

        Friday, November 4th, 2011 14:56

        33

        humm.. so what do you need? there is something that isn’t working? :)

        []’s

        0
  • Alex C

    Monday, August 22nd, 2011 11:25

    21

    For some reason, on SharePoint 2010, it was appending “#undefined” to all the table of contents items. So I modified the JS to this:
    if (id == "" || typeof id === "undefined") { //if it doesn't have only, of course
    id = "h" + tagNumber + "_" + i;
    cacheHN.attr('id', id);
    }

    It now works! Just in case anyone else runs into this issue.

    0
    • Liliana Gaete

      Tuesday, October 11th, 2011 15:24

      26

      Hi Alex,

      Your little modification to the script totally made my day. In WordPress I was also getting that #undefined issue. Now it works!

      Thanks!

      0
    • Rochester Oliveira

      Monday, August 22nd, 2011 14:25

      23

      And thanks for the input, I haven’t seen it :)

      []’s

      0
  • Alex C

    Tuesday, August 23rd, 2011 09:15

    24

    Documented how to use your amazing plugin with SharePoint. Thanks again for this great article and the code :)

    0
    • Rochester Oliveira

      Tuesday, August 23rd, 2011 17:30

      25

      Hi Alex,

      I’ve read it, and you won’t believe how glad I am. You really improved it, and your article is pretty well explained.

      Thanks A LOT!
      []’s
      Rochester

      0
  • Robin

    Friday, October 14th, 2011 06:54

    28

    Any chance of fixing this for the latest version of JQuery? The link come back as undefined and smooth scroll doesn’t work.

    0
    • Rochester Oliveira

      Friday, October 14th, 2011 14:35

      29

      Hi Robin!
      Haven’t see what is wrong, but I guess isn’t that hard to correct. I’ll try here and give you feedback!

      []’s

      0
  • Liliana Gaete

    Tuesday, October 11th, 2011 15:28

    27

    Great plugin!

    The best part about it is that there is nothing you have to hardcode. So, as long as there are H1s on the page, you are good to go :)

    Thank you so much!

    0
    • Rochester Oliveira

      Friday, October 14th, 2011 14:33

      30

      Hi Lilian,

      I’m Glad you liked it!

      Yeah, this is what I was tinking about.. And we’ll have more plugins soon :)

      []’s

      +1
  • RynoRn

    Thursday, May 17th, 2012 11:22

    38

    Hey,

    I fixed a bug in your plugin where it went to an infinite loop at this line:

    while(tagNumber != options.start) {
    appHTML = appHTML + “”;
    tagNumber–;
    }

    The tagnumber went under 0 so this loop never stopped and made the browsers to crash. You can find the fix here:
    https://gist.github.com/2719592

    0
    • Dainis Graveris

      Friday, May 18th, 2012 03:14

      39

      Hello RynoRn, oh my apologies – thank you for fixing it!

      0
  • goldsky

    Saturday, January 28th, 2012 14:26

    35

    Hello Roch,
    I edited your code here:
    1. fixed by omitting the last closing li, because after the first loop, the li closed its ul descendant.
    2. added beforeText and afterText

    cheers.

    0
    • Rochester Oliveira

      Monday, January 30th, 2012 02:30

      36

      Hey goldsky,

      I’m really glad you liked it so much to work on improvements.. Thanks a lot!

      []’s

      0
  • Sherwin Hermogenes

    Thursday, January 19th, 2012 19:13

    34

    Great plugin the effect is really very smooth.

    0
    • Rochester Oliveira

      Monday, January 30th, 2012 02:30

      37

      Cool, isn’t it, Sherwin?

      Thanks ;)

      0
  • Diego

    Friday, October 28th, 2011 15:46

    31

    sorry.
    Here is the code

    case (tagNumber < previous) : //it means that we went up but we don't know how much levels (e.g. from h3 to h2)
    appHTML = appHTML + "";
    while(tagNumber != previous) {
    appHTML = appHTML + "";
    previous--;
    }
    appHTML = appHTML + ""+ before +"" + txt + "";
    break;

    0
    • Diego

      Friday, October 28th, 2011 15:48

      32

      Here i go again…

      case (tagNumber < previous) : //it means that we went up but we don't know how much levels (e.g. from h3 to h2)
      appHTML = appHTML + "”;
      while(tagNumber != previous) {
      appHTML = appHTML + “”;
      previous–;
      }
      appHTML = appHTML + “”+ before +”lessThan a h ref=\”#”+ id + “\”>” + txt + “Lessthan/a>”;
      break;

      0
      • Rochester Oliveira

        Friday, November 4th, 2011 14:56

        33

        humm.. so what do you need? there is something that isn’t working? :)

        []’s

        0
  • Robin

    Friday, October 14th, 2011 06:54

    28

    Any chance of fixing this for the latest version of JQuery? The link come back as undefined and smooth scroll doesn’t work.

    0
    • Rochester Oliveira

      Friday, October 14th, 2011 14:35

      29

      Hi Robin!
      Haven’t see what is wrong, but I guess isn’t that hard to correct. I’ll try here and give you feedback!

      []’s

      0
  • Liliana Gaete

    Tuesday, October 11th, 2011 15:28

    27

    Great plugin!

    The best part about it is that there is nothing you have to hardcode. So, as long as there are H1s on the page, you are good to go :)

    Thank you so much!

    0
    • Rochester Oliveira

      Friday, October 14th, 2011 14:33

      30

      Hi Lilian,

      I’m Glad you liked it!

      Yeah, this is what I was tinking about.. And we’ll have more plugins soon :)

      []’s

      +1
  • Alex C

    Tuesday, August 23rd, 2011 09:15

    24

    Documented how to use your amazing plugin with SharePoint. Thanks again for this great article and the code :)

    0
    • Rochester Oliveira

      Tuesday, August 23rd, 2011 17:30

      25

      Hi Alex,

      I’ve read it, and you won’t believe how glad I am. You really improved it, and your article is pretty well explained.

      Thanks A LOT!
      []’s
      Rochester

      0
  • Alex C

    Monday, August 22nd, 2011 11:25

    21

    For some reason, on SharePoint 2010, it was appending “#undefined” to all the table of contents items. So I modified the JS to this:
    if (id == "" || typeof id === "undefined") { //if it doesn't have only, of course
    id = "h" + tagNumber + "_" + i;
    cacheHN.attr('id', id);
    }

    It now works! Just in case anyone else runs into this issue.

    0
    • Rochester Oliveira

      Monday, August 22nd, 2011 14:25

      23

      And thanks for the input, I haven’t seen it :)

      []’s

      0
    • Liliana Gaete

      Tuesday, October 11th, 2011 15:24

      26

      Hi Alex,

      Your little modification to the script totally made my day. In WordPress I was also getting that #undefined issue. Now it works!

      Thanks!

      0
  • Alex C

    Monday, August 22nd, 2011 10:24

    20

    Amazing stuff! Thanks for sharing this. I was looking to add this to a SharePoint publishing page and thought of creating from scratch until I came across this. Very nice. Thank you for creating this :)

    0
    • Rochester Oliveira

      Monday, August 22nd, 2011 14:24

      22

      Hi Alex, thank you!

      I’m glad you liked it
      []’s

      0
  • Rochester Oliveira

    Sunday, August 7th, 2011 05:02

    19

    Hi Arun,
    That’s why I’m here!

    Thank you!
    []’s

    0
  • egiova

    Saturday, June 11th, 2011 18:17

    17

    Thanks for sharing, it’s a very useful technique. I just want to add that a scroll to top will be a nice feature. But there’s so many options to implement this… it’s not a problem.

    I spent several years making internal manuals in various companies, and online classes too, it’s like making a mini-site with huge individual pages. I found that a non-fix vertical menu on a left sidebar was the more practical and intuitive way to implement a table of content. You want your reader focused on its reading, so the wiki format isn’t, in my feel, the best way to help somebody to learn and memorize something new. If you sum to this some tool-tips and modal windows, and your table of content, you have a fantastic and powerful tool for teaching.
    Once again, thanks for sharing this.

    0
    • Rochester Oliveira

      Sunday, June 12th, 2011 06:03

      18

      Hey egiova,

      As Abdelhadi said below it would be really helpful. It is pretty easy to add it, is just append some code (like this “top” link) while you are in each() loop.

      I agree with you, this must to be the best way to wiki-like sites, and I think it is really helpful for tutorials or roundups, so readers can go and read just what they want to learn (like if you are in a jquery plugins roundup and just want to see the sliders)..

      Thank you, again!
      []’s

      0
  • Rochester Oliveira

    Tuesday, June 7th, 2011 14:59

    15

    Thank you Incircle media!

    Don’t forget to check out our older articles, they are great too :D

    0
  • Yachika Verma

    Tuesday, June 7th, 2011 14:51

    14

    It seems very good, I liked it!

    0
    • Rochester Oliveira

      Tuesday, June 7th, 2011 15:00

      16

      Hi Yachika,

      I’m glad you liked it! This is why we all write :D

      []’s

      0
  • Rochester Oliveira

    Tuesday, June 7th, 2011 05:52

    12

    Hey Nanang, I think it is pretty useful too. Hope you find much more useful content here, on 1WD!

    []’s

    0
  • Rochester Oliveira

    Tuesday, June 7th, 2011 05:50

    11

    You are welcome enrusa :D

    []’s

    0
  • Julian

    Monday, June 6th, 2011 16:46

    10

    nice code,and good description to develop own jquery plugins. very
    usefull, thanks!

    0
    • Rochester Oliveira

      Monday, June 6th, 2011 19:42

      7

      Hey Julian, thank you!

      I’m glad you liked it, this is the reason we write this stuff :D

      []’s

      0
  • Maicon Sobczak

    Monday, June 6th, 2011 20:27

    9

    Is always helpful have the opportunity to learn how a plugin is estructured.

    0
    • Rochester Oliveira

      Tuesday, June 7th, 2011 05:53

      13

      Hey Maicon, did you notice how simple it is? I mean, with a few lines you can have a plugin, this is pretty cool, and jQuery is awsome!

      []’s

      0
  • Abdelhadi Touil

    Monday, June 6th, 2011 14:10

    8

    Very nice plugin; thanks very much for sharing.
    I think it’ll be better if it adds automatically a “top” link ine the of each section. What do you think?
    (Sorry for my bad English)

    0
    • Rochester Oliveira

      Monday, June 6th, 2011 16:34

      3

      Hey Abdelhadi, It is a good idea, and pretty simple do do, since our smooth scrolling can apply to this link also..

      Thank you for the insight!
      []’s

      0
  • wesley

    Monday, June 6th, 2011 18:20

    5

    Under what license is this file released? MIT?

    Thanks! Great stuff.

    0
    • Rochester Oliveira

      Monday, June 6th, 2011 19:41

      6

      Hey wesley, I think we missed it. MIT is ok to me, since you can do anything you want with this code and it has no warranty.

      Thank you for pointing it out, next time I’ll include this in our .zip !

      []’s

      0
  • Hasan

    Monday, June 6th, 2011 12:16

    1

    it might be very good if we see a little demo for this script

    0
    • Hasan

      Monday, June 6th, 2011 12:18

      2

      Sorry ive missed it out. I ve seen it. Very nice! Thanks! :)

      0
      • Rochester Oliveira

        Monday, June 6th, 2011 16:35

        4

        Hey Hassan, don’t worry about it :D I do this all the time.. :)

        Thank you!

        []’s

        0

Comments are closed.

54.81.112.187 - unknown - unknown - US