You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于URL查询参数通过JavaScript为动态生成目录的指定列表项范围添加类名

Hey there! Let's build this dynamic table of contents with URL-based range highlighting step by step. We'll cover auto-generating the TOC from your page's H1-H6 headings, then adding the logic to highlight specific sections (and their subtrees) using start and end query parameters.

1. How This Will Work

First, we'll:

  • Traverse all H1-H6 elements on the page, build a nested TOC structure that matches the heading hierarchy.
  • Assign a unique iteration index to each <li> in the TOC (matching the order you described in your example).
  • Parse the URL's start and end parameters, then highlight all <li> items (and their nested children) whose index falls within that range.
  • Do nothing if there are no valid parameters, keeping the default TOC style.

2. Full Implementation Code

2.1 HTML Base (Where the TOC Will Live)

First, add an empty <nav> element to your page where the TOC will be injected:

<nav id="dynamic-toc">
  <div class="container">
    <!-- TOC will be generated here -->
  </div>
</nav>

2.2 JavaScript Logic

This script handles both TOC generation and the highlighting logic:

// Generate dynamic TOC from H1-H6 headings
function generateTOC() {
  const tocContainer = document.querySelector('#dynamic-toc .container');
  const headings = Array.from(document.querySelectorAll('h1, h2, h3, h4, h5, h6'));
  const tocTree = document.createElement('ul');
  let currentLevel = 0;
  let currentParent = tocTree;
  let iterationIndex = 0; // Track the iteration order of <li> elements

  headings.forEach(heading => {
    const headingLevel = parseInt(heading.tagName.charAt(1));
    const listItem = document.createElement('li');
    iterationIndex++;
    // Add data attribute to track iteration order
    listItem.dataset.iterationIndex = iterationIndex;
    
    const link = document.createElement('a');
    link.href = `#${heading.id || `heading-${iterationIndex}`}`;
    link.textContent = heading.textContent;
    // If heading has no ID, assign one for anchor linking
    if (!heading.id) heading.id = `heading-${iterationIndex}`;
    
    listItem.appendChild(link);

    // Adjust nested level based on heading hierarchy
    if (headingLevel > currentLevel) {
      // Create new nested ul under the last list item
      const newUl = document.createElement('ul');
      currentParent.lastElementChild.appendChild(newUl);
      currentParent = newUl;
    } else if (headingLevel < currentLevel) {
      // Move up the hierarchy to the correct parent
      for (let i = 0; i < currentLevel - headingLevel; i++) {
        currentParent = currentParent.parentElement.parentElement;
      }
    }

    currentParent.appendChild(listItem);
    currentLevel = headingLevel;
  });

  tocContainer.appendChild(tocTree);
}

// Highlight TOC items based on URL query parameters
function highlightTOCRange() {
  const urlParams = new URLSearchParams(window.location.search);
  const start = parseInt(urlParams.get('start'));
  const end = parseInt(urlParams.get('end'));

  // Only run if both start and end are valid numbers, and start <= end
  if (isNaN(start) || isNaN(end) || start > end || start < 1) return;

  const allTOCItems = document.querySelectorAll('#dynamic-toc li[data-iteration-index]');
  
  allTOCItems.forEach(item => {
    const index = parseInt(item.dataset.iterationIndex);
    if (index >= start && index <= end) {
      // Add highlight class to the item and all its nested children
      item.classList.add('toc-highlighted');
      // Recursively add class to all nested li elements
      const nestedItems = item.querySelectorAll('li');
      nestedItems.forEach(nested => nested.classList.add('toc-highlighted'));
    }
  });
}

// Initialize everything when the page loads
document.addEventListener('DOMContentLoaded', () => {
  generateTOC();
  highlightTOCRange();
});

2.3 CSS Styles

Include these styles to format the TOC and the highlighted sections:

/* Base TOC Styles */
ul, li { list-style: none; padding: 0; margin: 0; }
li { margin-top: 1px; }
li>ul { margin-top: 1em; margin-left: 2em; }
a { 
  line-height: 2em; 
  background: #2C82C9; 
  display: inline-block; 
  color: #fff; 
  padding: 2px 8px; 
  border-radius: 8px;
  text-decoration: none;
}
.container { max-width: 80%; margin: 2em auto; }

/* Highlight Styles */
.toc-highlighted a {
  background: #FF6B6B; /* Bright red for highlighted top-level items */
}
.toc-highlighted ul li a {
  background: #FF8E8E; /* Lighter red for nested highlighted items */
}

3. How It Matches Your Requirements

  • No parameters: When the URL has no start/end params, the TOC uses the default blue links with no highlighting.
  • ?start=1&end=6: The first 6 iterated <li> items (and all their nested sub-items) get the red highlight styles.
  • ?start=2&end=4: Iteration items 2, 3, 4 (and their subtrees) are highlighted exactly as you described.

4. Key Notes

  • The script assigns unique IDs to headings that don't have one, so anchor links work correctly.
  • The data-iteration-index attribute ensures we're targeting the exact order of <li> elements as they're generated, matching your example's numbering.
  • We validate the URL parameters to avoid errors from invalid values (like non-numbers or start > end).

内容的提问来源于stack exchange,提问作者markb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:49:25