(function ($) { $.fn.stoc = function (options) { //Our default options var defaults = { depth: 6, //how many hN should we search start: 1, //which hN will be the first (and after it we go just deeper) stocTitle: "

Contents

", //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 function () { //"cache" our target and search objects obj = $(this); //target //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 = ""; obj.nextUntil('h1').each(function () { if ($(this).tagName == "h2" || $(this).tagName == "h3") { //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 + ">
  • " + before + "" + txt + ""; previous = tagNumber; break; case (tagNumber == previous) : //it means that stay on the same level (e.g. h3 and stay on it) appHTML = appHTML + "
  • " + before + "" + txt + ""; 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 + "
  • "; previous--; } appHTML = appHTML + "
  • " + before + "" + txt + "
  • "; break; } i++; } }); //corrects our last item, because it may have some opened ul's while (tagNumber != options.start) { appHTML = appHTML + ""; tagNumber--; } //append our html to our object appHTML = options.stocTitle + "<" + options.listType + ">" + appHTML + ""; 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);