jQuery Plugin Author: zhangxinxu Published: April 30, 2018 Compatible: IE8+, Modern Browsers, Mobile

titleNav.js: A Small jQuery Plugin for Auto-Generating Navigation from Article / Document Headings

Technical documentation and long showcase pages are divided into sections with headings. titleNav.js automatically collects your document headings (<h3>, etc.), builds a responsive floating or fixed navigation menu, tracks scrolling with active highlighting, handles smooth jumps, and optimizes edge cases such as reaching page bottom.

1 Quick Start: Single-Line Automatic Sidebar Generation

Simply select your heading elements with jQuery and invoke .titleNav(). The plugin automatically creates the navigation wrapper <div class="title-nav-ul">, extracts the heading titles into <a class="title-nav-li"> anchors, switches position to fixed when scrolling past the top threshold, and applies the .active class to the heading currently in view.

Code: HTML, JS & Matching CSS
javascript & css
<!-- 1. JavaScript: Single line invocation -->
<script>
$('h3').titleNav();
</script>

<!-- 2. CSS: Matching styles from zhangxinxu's article -->
<style>
.title-nav-ul {
    width: 200px;
    border: 1px solid #ccc;
    background-color: #fff;
    box-shadow: 1px 1px 3px rgba(0,0,0,.25);
    position: absolute;
    top: 160px; right: 16px;
}
.title-nav-li {
    display: block;
    padding: 10px;
    text-decoration: none;
    color: inherit;
}
.title-nav-li.active {
    font-weight: bold;
}
.title-nav-li:hover {
    background-color: #f0f0f0;
}
</style>
Result: Live Interactive Showcase (LuLu UI Documentation Sample)
Scroll the article below or click navigation links: Active: 1. Why the name LuLu?

1. Why the name LuLu?

LuLu UI is a lightweight, clean front-end UI framework designed for PC modern web interfaces. The name "LuLu" originates from a playful and melodious phonetic sound, symbolizing simplicity, transparency, and a design philosophy focused on native web standards.

Unlike heavyweight frameworks that override default browser mechanics with excessive custom elements, LuLu prioritizes semantic HTML form elements and accessible document hierarchy.

2. Why use LuLu?

Traditional frameworks often burden your project with massive CSS and JS bundles, even when you only need standard buttons and dialogs. LuLu keeps components decoupled: every single widget can function independently without a monolithic core.

Tip: LuLu UI is tailored specifically for developers who appreciate minimal dependencies and standard CSS styling.

It requires zero compilation steps—simply include the stylesheet and script tag, or import individual plugins as needed.

3. Design philosophy

"Design for the future, code for the present." LuLu emphasizes progressive enhancement: browsers with advanced capabilities enjoy seamless transitions, while older legacy environments retain complete functional accessibility.

Navigation structures like in-page heading trees enhance usability on long technical pages, enabling users to jump straight to their points of interest without repetitive manual scrolling.

4. Highlight me when scrolling to bottom

This is the terminal section of our document. As you scroll down to this final paragraph, observe how titleNav.js automatically detects the bottom boundary and marks this last item with the active state!

(End of LuLu UI overview demonstration content)

2 Horizontal Navigation Bar: Custom Nav Element & Flex Styling

As the article explains: "If you want a horizontal navigation fixed at the top, simply adjust the styles of the .title-nav-ul and .title-nav-li classes." You can also pass an existing navigation container element via the nav option.

Code: Horizontal CSS & Custom Nav Option
javascript & css
/* CSS: Switch from vertical sidebar to fixed top flexbar */
.title-nav-ul.horizontal {
    position: sticky;
    top: 0;
    width: 100%;
    display: flex;
    background-color: #1e293b;
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    z-index: 60;
}
.title-nav-ul.horizontal .title-nav-li {
    display: inline-flex;
    padding: 10px 18px;
    color: #94a3b8;
    border-bottom: 2px solid transparent;
}
.title-nav-ul.horizontal .title-nav-li.active {
    color: #38bdf8;
    border-bottom-color: #38bdf8;
    font-weight: 600;
}

/* JavaScript: Pass target nav element and scroll container */
$('#horizontal-article h3').titleNav({
    nav: $('#horizontal-nav-bar'),
    container: $('#demo2-viewport'),
    offsetTop: 0
});
Result: Live Interactive Showcase (Sticky Horizontal Header)
Sticky horizontal navigation stays pinned at container top:

1. Architecture Overview

The modular architecture of titleNav.js isolates DOM generation from scroll observation. When an existing element is supplied via the nav option, the plugin populates it without altering its outer structure.

This allows developers to freely embed the navigation into existing application headers, side drawers, or tab bars while retaining all scroll synchronization features.

2. Declarative Heading Collection

Any selector can be passed into jQuery—whether targeting standard $('h3') tags, multi-level $('h2, h3') elements, or specific CSS classes like $('.doc-title').

The plugin respects document source order, generating matching navigational links in the exact sequence they appear in your markup.

3. Performance Optimization

Scroll events are handled efficiently with minimal layout thrashing. Calculations reuse cached bounding boxes during smooth transitions, preventing stutter even on pages with extensive text and nested layouts.

4. Cross-Device Compatibility

Compatible with desktop browsers and mobile touch devices. By avoiding fixed touch-action hijacking, native momentum scrolling remains smooth and responsive.

3 Scoped Container Scrolling & Offset Tuning (container & offsetTop)

By default, the plugin observes $(window) scrolling and switches to fixed positioning at offsetTop: 20 (20px). When embedding headings inside an overflow container or modal dialog, specify container: $('#my-pane'). Adjust offsetTop to align headings with your visual header boundary.

Code: Configuring container and offsetTop
javascript
// API Options Matrix:
// - container: Scoped scroll element ($('#scroll-box') instead of $(window))
// - offsetTop: Distance from top edge where headings trigger active state
$('#demo3-viewport h3').titleNav({
    container: $('#demo3-viewport'),
    offsetTop: 30  // Switches fixed / active threshold at 30px
});
Result: Live Interactive Offset Playground (Tweak offsetTop in real time)
Change offsetTop and watch the red dashed threshold line:
offsetTop:
Active Threshold: offsetTop = 30px

1. Parameter: offsetTop

The offsetTop parameter specifies the pixel distance from the top edge when the navigation switches to fixed positioning (default is 20). Set it to 0 if you want the navigation flush with the browser top.

Notice the red dashed indicator above. When a heading crosses that exact boundary line during scrolling, titleNav.js triggers the active highlight!

2. Parameter: container

By default, container is $(window). In this interactive demo, it is explicitly bounded to the local viewport $('#demo3-viewport').

This flexibility ensures titleNav.js works flawlessly inside tabbed dashboards, split-pane editors, side drawer panels, and modal windows.

3. Parameter: nav

When nav is null (the default), the navigation element is automatically generated. When an existing element or selector is passed, titleNav.js connects to that element directly.

4. Verification & Testing

Try toggling between 0px, 30px, and 60px using the toolbar buttons above, then scroll up and down. The heading activates precisely when passing the dashed guide line!

4 Intelligent Bottom-Edge Detection for Short Ending Sections

A notorious flaw in standard scrollspy implementations is that short ending sections (like "Conclusion" or "References") never reach the top offset threshold before scrolling hits the bottom limit, leaving the previous item mistakenly highlighted. titleNav.js includes thoughtful edge-case optimizations to guarantee the final navigation item activates properly when scrolled to the end.

Code: Bottom Limit Check Implementation
javascript
// Excerpt from titleNav.js scroll event handler:
var scrollTop = $container.scrollTop();
var containerHeight = $container.height();
var scrollHeight = $container[0].scrollHeight;

// Edge case: When scrolled to the bottom of the container,
// automatically highlight the last navigation item.
if (scrollTop + containerHeight >= scrollHeight - 8) {
    $navItems.removeClass('active');
    $navItems.last().addClass('active');
    return;
}
Result: Live Interactive Showcase (Edge-Case Demonstration)
Notice Section 4 is very short—yet it turns bold when bottom is reached:

1. Normal Content Section

This section has plenty of explanatory paragraphs. As you scroll through it, standard threshold detection works effortlessly because the heading has ample room to reach the top edge.

In document readers, early sections are usually substantial enough that traditional offset math is sufficient.

2. Another Regular Chapter

Continuing down the page, each menu item highlights consecutively as expected.

Smooth scrolling animations also make transitions pleasant when navigating between distant sections.

3. Approaching the End

The document is now nearing completion. The upcoming section below contains only a single brief sentence!

4. Highlight me when scrolling to bottom

(Very short terminal section) Reaching the bottom boundary forces this item to highlight instantly!

5 API Reference & Generated DOM Inspection

Full specification of the $().titleNav(options) parameter object and the internal HTML structure generated by the plugin.

Code: Generated HTML DOM Structure
html
<!-- Auto-generated navigation markup created by titleNav.js -->
<div class="title-nav-ul">
  <a href="javascript:" class="title-nav-li active">1. Why the name LuLu?</a>
  <a href="javascript:" class="title-nav-li">2. Why use LuLu?</a>
  <a href="javascript:" class="title-nav-li">3. Design philosophy</a>
  <a href="javascript:" class="title-nav-li">4. Highlight me when scrolling to bottom</a>
</div>
Result: Options Matrix & Live DOM Inspector
Parameter Default Type Description
nav null Object Represents the navigation element. Defaults to null, meaning the plugin automatically generates the navigation container rather than using an existing element on the page.
container $(window) Object The scroll container element; must be a jQuery wrapper object. Defaults to browser window scrolling.
offsetTop 20 Number Distance in pixels from the top edge when the navigation switches to fixed positioning. Can be set to 0 if the navigation sticks flush to the top.

Live DOM Inspector (Reflects Section 1's Generated Nav in Real Time):

“You are in the southern sun as snow flurries blow,
I am in the cold northern night where spring flowers grow.
If time allows before darkness falls, I will forget your eyes;
A lifetime spent in vain, chasing a dream that never dies.”
— Shared by zhangxinxu (Hebe Tien performing Nan Shan Nan at Beijing Strawberry Music Festival)