原创纯JavaScript实现文章自动导航菜单插件

文章目录

原创纯JavaScript实现文章自动导航菜单插件

下面是一个纯JavaScript实现的文章自动导航菜单功能,能够从指定容器中提取标题生成导航,并支持平滑滚动到对应锚点。

资源已经上传到csdn资源下载模块,点击原创纯JavaScript+css实现文章自动导航菜单插件下载完整项目

核心代码

插件NavGenerator.js代码如下

/**
 * 文章自动导航菜单生成器
 * @param {Object} options - 配置选项
 * @param {string} options.contentContainerId - 文章内容容器ID
 * @param {string} options.navContainerId - 导航菜单容器ID
 * @param {Array} options.selectors - 要提取的标题选择器,按优先级排序
 * @param {string} options.navTitle - 导航菜单标题
 */
class ArticleNavGenerator {
   
   
    constructor(options) {
   
   
        // 默认配置
        const defaultOptions = {
   
   
            contentContainerId: 'article-content',
            navContainerId: 'nav-container',
            selectors: ['h1', 'h2', 'h3', 'h4'],
            navTitle: '文章导航'
        };

        // 合并配置
        this.options = {
   
    ...defaultOptions, ...options };

        // 获取容器元素
        this.contentContainer = document.getElementById(this.options.contentContainerId);
        this.navContainer = document.getElementById(this.options.navContainerId);

        // 存储标题元素和导航项
        this.headings = [];
        this.navItems = [];

        // 初始化
        if (this.contentContainer && this.navContainer) {
   
   
            this.init();
        } else {
   
   
            console.error('内容容器或导航容器不存在');
        }
    }

    /**
     * 初始化函数,执行所有初始化操作
     */
    init() {
   
   
        this.collectHeadings();
        this.generateAnchors();
        this.generateNavMenu();
        this.setupEventListeners();
    }

    /**
     * 从内容容器中收集所有标题元素
     */
    collectHeadings() {
   
   
        // 临时存储所有标题
        const allHeadings = [];

        // 遍历所有指定的标题选择器
        this.options.selectors.forEach(selector => {
   
   
            const elements = this.contentContainer.querySelectorAll(selector);
            allHeadings.push(...elements);
        });

        // 按在文档中的位置排序
        this.headings = allHeadings.sort((a, b) => {
   
   
            return a.offsetTop - b.offsetTop;
        });
    }

    /**
     * 为每个标题生成唯一的锚点ID
     */
    generateAnchors() {
   
   
        const idMap = {
   
   };

        this.headings.forEach(heading => {
   
   
            // 从标题文本生成基础ID
            let baseId = heading.textContent.trim()
                .toLowerCase()
                .replace(/\s+/g, '-')
                .replace(/[^a-z0-9-]/g, '');

            // 确保ID唯一性
            if (idMap[baseId]) {
   
   
                idMap[baseId]++;
                baseId = `${
     
     baseId}-${
     
     idMap[baseId]}`;
            } else {
   
   
                idMap[baseId] = 1;
            }

            // 设置ID
            heading.id = baseId;

            // 存储ID用于导航
            heading.dataset.anchorId = baseId;

            // 存储标题级别
            const level = parseInt(heading.tagName.substring(1));
            heading.dataset.level = level;
        });
    }

    /**
     * 生成导航菜单HTML并插入到导航容器
     */
    generateNavMenu(
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值