1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | (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: "<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 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 + "><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); |