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

2016-04-17 20:28:10 +08:00
 cqcn1991

想拿 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) {这里的几个变量怎么来的都没看懂....

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

2021 次点击
所在节点    问与答
11 条回复
Vladimir
2016-04-17 20:39:13 +08:00
cqcn1991
2016-04-17 20:41:27 +08:00
@Vladimir 原来是这个 API
我查的是 innerHTML.replace ,查了半天没找到
我仔细看看,谢谢
jamesxu
2016-04-17 20:42:23 +08:00
@cqcn1991
你错了, innerHTML 返回的是一个字符串, JS 字符串本身就有 replace 方法
hxsf
2016-04-17 20:59:03 +08:00
function (str, openLevel, titleText, closeLevel) 的参数就是 这个 正则的 /<h([\d])>([^<]+)<\/h([\d])>/gi 匹配结果
cqcn1991
2016-04-17 21:05:01 +08:00
@hxsf 我靠...就是一段正则可以返回 4 个参数!?
原来是这样。我并不会正则
hxsf
2016-04-17 21:08:36 +08:00
@cqcn1991 正则返回的要看正则怎么写的,你简单搜一下 正则 元组
subpo
2016-04-17 21:09:08 +08:00
@cqcn1991 innerHTML 是一个 api replace 是另一个
hxsf
2016-04-17 21:15:57 +08:00
@cqcn1991 一楼的 api ,你看一下,自己试一下就知道了。
lwbjing
2016-04-17 23:21:45 +08:00
@cqcn1991 说的简单点就是,正则里用括号包了 n 个,后面函数就可以跟 1 + n 个参数... 1 是全文匹配的,每个 n 是单个括号匹配的内容...
cqcn1991
2016-04-17 23:23:41 +08:00
@lwbjing 太感谢了!
wdhwg001
2016-04-18 01:14:15 +08:00
犯了大忌…不应该用正则处理 html 标签的,因为 js 的正则没有平衡组,用正则会在数据不可信任的时候出现各种 bug 和漏洞…

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/271808

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX