V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
cqcn1991
V2EX  ›  问与答

真诚的求一段 js 代码的讲解

  •  
  •   cqcn1991 · 2016-04-17 20:28:10 +08:00 · 2084 次点击
    这是一个创建于 3147 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想拿 HTML 直接生成 table of contents, 用 js 做 于是找到了这个 http://stackoverflow.com/questions/187619/is-there-a-javascript-solution-to-generating-a-table-of-contents-for-a-page

    原文如下

    window.onload = function () {
        var toc = "";
        var level = 0;
        
        document.getElementById("contents").innerHTML =
            document.getElementById("contents").innerHTML.replace(
                /<h([\d])>([^<]+)<\/h([\d])>/gi,
                function (str, openLevel, titleText, closeLevel) {
                    if (openLevel != closeLevel) {
                        return str;
                    }
    
                    if (openLevel > level) {
                        toc += (new Array(openLevel - level + 1)).join("<ul>");
                    } else if (openLevel < level) {
                        toc += (new Array(level - openLevel + 1)).join("</ul>");
                    }
    
                    level = parseInt(openLevel);
    
                    var anchor = titleText.replace(/ /g, "_");
                    toc += "<li><a href=\"#" + anchor + "\">" + titleText
                        + "</a></li>";
                    
                    return "<h" + openLevel + "><a name=\"" + anchor + "\">"
                        + titleText + "</a></h" + closeLevel + ">";
                }
            );
    
        if (level) {
            toc += (new Array(level + 1)).join("</ul>");
        }
    
        document.getElementById("toc").innerHTML += toc;
    };
    

    Your page should be structured something like this:

    <body>
        <div id="toc">
            <h3>Table of Contents</h3>
        </div>
        <hr/>
        <div id="contents">
            <h1>Fruits</h1>
            <h2>Red Fruits</h2>
            <h3>Apple</h3>
            <h3>Raspberry</h3>
            <h2>Orange Fruits</h2>
            <h3>Orange</h3>
            <h3>Tangerine</h3>
            <h1>Vegetables</h1>
            <h2>Vegetables Which Are Actually Fruits</h2>
            <h3>Tomato</h3>
            <h3>Eggplant</h3>
        </div>
    </body>
    

    You can see it in action at http://magnetiq.com/exports/toc.htm (Works in IE, FF, Safari, Opera)

    主要就是document.getElementById("contents").innerHTML.replace(后面的看不懂, function (str, openLevel, titleText, closeLevel) {这里的几个变量怎么来的都没看懂....

    希望有前辈可以帮忙讲解一下...

    11 条回复    2016-04-18 01:14:15 +08:00
    cqcn1991
        2
    cqcn1991  
    OP
       2016-04-17 20:41:27 +08:00
    @Vladimir 原来是这个 API
    我查的是 innerHTML.replace ,查了半天没找到
    我仔细看看,谢谢
    jamesxu
        3
    jamesxu  
       2016-04-17 20:42:23 +08:00
    @cqcn1991
    你错了, innerHTML 返回的是一个字符串, JS 字符串本身就有 replace 方法
    hxsf
        4
    hxsf  
       2016-04-17 20:59:03 +08:00
    function (str, openLevel, titleText, closeLevel) 的参数就是 这个 正则的 /<h([\d])>([^<]+)<\/h([\d])>/gi 匹配结果
    cqcn1991
        5
    cqcn1991  
    OP
       2016-04-17 21:05:01 +08:00
    @hxsf 我靠...就是一段正则可以返回 4 个参数!?
    原来是这样。我并不会正则
    hxsf
        6
    hxsf  
       2016-04-17 21:08:36 +08:00
    @cqcn1991 正则返回的要看正则怎么写的,你简单搜一下 正则 元组
    subpo
        7
    subpo  
       2016-04-17 21:09:08 +08:00
    @cqcn1991 innerHTML 是一个 api replace 是另一个
    hxsf
        8
    hxsf  
       2016-04-17 21:15:57 +08:00
    @cqcn1991 一楼的 api ,你看一下,自己试一下就知道了。
    lwbjing
        9
    lwbjing  
       2016-04-17 23:21:45 +08:00
    @cqcn1991 说的简单点就是,正则里用括号包了 n 个,后面函数就可以跟 1 + n 个参数... 1 是全文匹配的,每个 n 是单个括号匹配的内容...
    cqcn1991
        10
    cqcn1991  
    OP
       2016-04-17 23:23:41 +08:00
    @lwbjing 太感谢了!
    wdhwg001
        11
    wdhwg001  
       2016-04-18 01:14:15 +08:00 via iPhone
    犯了大忌…不应该用正则处理 html 标签的,因为 js 的正则没有平衡组,用正则会在数据不可信任的时候出现各种 bug 和漏洞…
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2433 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:02 · PVG 08:02 · LAX 16:02 · JFK 19:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.