Gumshoe Documentation

repository·master·Indexed 21 days ago

https://github.com/cferdinandi/gumshoe

Gumshoe is a lightweight, framework-agnostic, vanilla JavaScript scrollspy library (version 5.1.2) that highlights navigation links based on the user's scroll position. It supports nested navigation, reflow detection for responsive designs, and custom offsets for fixed headers. The library provides a public API with setup(), detect(), and destroy() methods, and can emit custom gumshoeActivate and gumshoeDeactivate events.

Tokens
2.7K
Snippets
10
Records
12
Agent score
72%

What's inside Gumshoe

  1. Configure nested navigation

    master

    If your navigation menu has multiple levels, you can enable nested support. When enabled, Gumshoe applies an active class to the parent list items of the currently active link.

    Set nested: true and optionally provide a nestedClass name in the configuration object.

    var spy = new Gumshoe('#my-awesome-nav a', {
    	nested: true,
    	nestedClass: 'active-parent'
    });
  2. Account for fixed headers with offset

    master

    If your site has a fixed header, you can use the offset setting to prevent the active state from triggering too early.

    The offset option accepts:

    • A number (static offset).
    • A function that returns a number (dynamic offset).

    Using a function is preferred if you need to calculate the header's height dynamically.

    // Get the header
    var header = document.querySelector('#my-header');
    
    // Initialize Gumshoe with dynamic offset
    var spy = new Gumshoe('#my-awesome-nav a', {
    	offset: function () {
    		return header.getBoundingClientRect().height;
    	}
    });
  3. Quickstart: Set up a basic scrollspy

    master

    To implement a basic scrollspy, follow these four steps:

    1. Include Gumshoe: Add the script via NPM or CDN.
    2. Add Markup: Create a list of anchor links that point to your content IDs.
    3. Initialize: Instantiate Gumshoe by passing a selector for the navigation links.
    4. Add Styling: Gumshoe adds an .active class to the list item (<li>) and the content element, but you must define the CSS yourself.
    <!-- 1. Include Gumshoe -->
    <script src="https://cdn.jsdelivr.net/gh/cferdinandi/gumshoe@4.0.0/dist/gumshoe.polyfills.min.js"></script>
    
    <!-- 2. Add Markup -->
    <ul id="my-awesome-nav">
    	<li><a href="#eenie">Eenie</a></li>
    	<li><a href="#meenie">Meenie</a></li>
    </ul>
    
    <!-- 3. Initialize -->
    <script>
    	var spy = new Gumshoe('#my-awesome-nav a');
    </script>
    
    <!-- 4. Add Styling -->
    <style>
    #my-awesome-nav li.active a {
    	font-weight: bold;
    }
    </style>```
    

    // HTML structure <ul id="my-awesome-nav"> <li><a href="#eenie">Eenie</a></li> <li><a href="#meenie">Meenie</a></li> </ul>

    // Initialization var spy = new Gumshoe('#my-awesome-nav a');

    // CSS #my-awesome-nav li.active a { font-weight: bold; }

  4. Install Gumshoe

    master

    You can include Gumshoe in your project via NPM, CDN, or direct download.

    There are two versions available:

    1. Standalone version: Use this if you are providing your own polyfills or want to avoid extra weight.
    2. Polyfills version: Includes polyfills for closest() and CustomEvent(), which is recommended for supporting older browsers (IE 9+).

    NPM

    npm install gumshoejs

    CDN (jsDelivr)

    It is recommended to use a specific version number to prevent breaking changes.

    <!-- Get a specific version (Recommended) -->
    <script src="https://cdn.jsdelivr.net/gh/cferdinandi/gumshoe@4.0.0/dist/gumshoe.polyfills.min.js"></script>
    
    <!-- Get patch fixes within a minor version -->
    <script src="https://cdn.jsdelivr.net/gh/cferdinandi/gumshoe@4.0/dist/gumshoe.polyfills.min.js"></script>
    
    <!-- Get minor updates and patch fixes within a major version -->
    <script src="https://cdn.jsdelivr.net/gh/cferdinandi/gumshoe@4/dist/gumshoe.polyfills.min.js"></script>
    npm install gumshoejs
  5. Configure reflow detection

    master

    If your content layout changes based on the viewport (e.g., responsive design changes that alter element positions), you must enable reflow to allow Gumshoe to update its internal calculations.

    Set reflow: true in the configuration object. This is disabled by default.

    var spy = new Gumshoe('#my-awesome-nav a', {
    	reflow: true
    });
  6. Gumshoe Public Methods

    master

    The Gumshoe instance exposes the following methods:

    • setup(): Performs all necessary background calculations. Call this if you dynamically add navigation items to the DOM after initialization.
    • detect(): Manually triggers the detection logic to activate the link corresponding to the content currently in the viewport.
    • destroy(): Destroys the current Gumshoe instance.
  7. Listen for Gumshoe custom events

    master

    If events is set to true (the default), Gumshoe emits two custom events that bubble up from the list item:

    • gumshoeActivate: Emitted when a link becomes active.
    • gumshoeDeactivate: Emitted when a link is no longer active.

    The event.detail object contains:

    • link: The anchor element.
    • content: The content element.
    • settings: The settings used for the current instantiation.
    // Listen for activate events
    document.addEventListener('gumshoeActivate', function (event) {
    
    	// The list item
    	var li = event.target;
    
    	// The link
    	var link = event.detail.link;
    
    	// The content
    	var content = event.detail.content;
    
    }, false);
  8. Configure Gumshoe options

    master

    When instantiating Gumshoe, you can provide an options object to customize its behavior.

    OptionTypeDefaultDescription
    navClassString'active'The class added to the navigation item's parent <li> when active.
    contentClassString'active'The class added to the content element when active.
    nestedBooleanfalseWhether to support nested navigation. If true, parent <li> elements will also receive the nestedClass.
    nestedClassString'active'The class added to parent <li> elements in nested navigation.
    offsetNumber0The pixel offset used for calculating when an element is in view. Can also be a function returning a number.
    reflowBooleanfalseIf true, Gumshoe will listen for resize events to re-sort content and re-detect active items.
    eventsBooleantrueWhether to emit custom DOM events (gumshoeActivate and gumshoeDeactivate).
    var options = {
      navClass: 'active',
      contentClass: 'active',
      nested: true,
      nestedClass: 'parent-active',
      offset: 100,
      reflow: true,
      events: true
    };
    
    var gumshoe = new Gumshoe('.nav-link', options);
  9. Gumshoe Configuration Options

    master

    When instantiating new Gumshoe(selector, options), you can pass the following settings:

    OptionTypeDefaultDescription
    navClassstring'active'Class applied to the navigation list item (<li>).
    contentClassstring'active'Class applied to the content element.
    nestedbooleanfalseIf true, adds classes to parents of the active link.
    nestedClassstring'active'Class applied to the parent items in nested navigation.
    offsetnumber or function0Distance from the top of the page to activate content.
    reflowbooleanfalseIf true, listens for reflows to update calculations.
    eventsbooleantrueIf true, emits custom gumshoeActivate and gumshoeDeactivate events.
  10. Initialize Gumshoe

    master

    To use Gumshoe, instantiate the Gumshoe constructor by passing a CSS selector for your navigation items and an optional options object. The constructor automatically initializes the scrollspy, detects the currently active content, and attaches scroll event listeners.

    Note: The navigation items must use hash links (e.g., <a href="#section-id">) that correspond to the id of the content elements you want to track.

    // Example initialization
    var gumshoe = new Gumshoe('.nav-item', {
      navClass: 'is-active',
      contentClass: 'is-active'
    });
  11. Use Gumshoe public API methods

    master

    The Gumshoe constructor returns an object containing the following public methods:

    • setup(): Manually triggers the setup process, which queries the DOM for navigation items and maps them to their corresponding content elements via their hash links.
    • detect(): Manually triggers the detection of the currently active content based on the scroll position.
    • destroy(): Cleans up the instantiation by deactivating the current item, removing window event listeners (scroll and optionally resize), and resetting internal variables.
    var gumshoe = new Gumshoe('.nav-link');
    
    // Manually trigger detection
    gumshoe.detect();
    
    // Clean up and remove event listeners
    gumshoe.destroy();
  12. Listen to Gumshoe custom events

    master

    If events is set to true in the options, Gumshoe emits custom DOM events when navigation items are activated or deactivated. These events are dispatched from the parent <li> of the navigation link.

    Events

    • gumshoeActivate: Dispatched when a navigation item and its content become active.
    • gumshoeDeactivate: Dispatched when a navigation item and its content are no longer active.

    Event Detail

    The detail object contains:

    • link: The navigation element (the <a> tag).
    • content: The content element being activated/deactivated.
    • settings: The Gumshoe settings object used for this instance.
    var gumshoe = new Gumshoe('.nav-link', { events: true });
    
    // Listen for activation on the document or a specific container
    document.addEventListener('gumshoeActivate', function (event) {
      console.log('Activated:', event.detail.link);
      console.log('Content:', event.detail.content);
    });
    
    document.addEventListener('gumshoeDeactivate', function (event) {
      console.log('Deactivated:', event.detail.link);
    });