将同层级的h1~h6标签转为不同层级关系的列表

昨天晚上写随笔时对博客园的文章目录产生了好奇心,原本同级的标题标签是怎么转化为不同层级关系的列表呢?对此我展开了思考,终于,在今天早上按照自己的想法将转化的逻辑写了出来。

(博客园文章目录图)
image

问题分析

  1. 要对一个元素进行操作,就要先获取元素。

  2. 既然每种标签对应不同层级那么先用枚举法将它们的权重一个个枚举出来。

  3. 最后比较标签权重,对标签进行层级划分。

实现

<div id="content">
        <h1>这是h1</h1>
        <h2>这是h2</h2>
        <h2>这是h2</h2>
        <h3>这是h3</h3>
        <h5>这是h5</h5>
        <h3>这是h3</h3>
        <h5>这是h5</h5>
        <h4>这是h4</h4>
        <h4>这是h4</h4>
        <h2>这是h2</h2>
        <h6>这是h6</h6>
</div>

将上述代码转为不同层级关系的列表

首先先获取content元素结点

var content = document.getElementById('content');

创建一个节点类封装节点需要的信息

function Node() {
    this.node; // 存储元素节点
    this.element = document.createElement('li'); // 创建一个元素结点
    this.weight; // 权重
    this.parentNode = null; // 父节点

    function getWeight(node) { //获取元素节点的权重
        var weight;
        switch (node.tagName) {
            case 'H1':
                weight = 6;
                break;
            case 'H2':
                weight = 5;
                break;
            case 'H3':
                weight = 4;
                break;
            case 'H4':
                weight = 3;
                break;
            case 'H5':
                weight = 2;
                break;
            case 'H6':
                weight = 1;
                break;
            default:
                // 非标题标签权重为0
                weight = 0;
                break;
        }
        return weight;
    }
    this.setNode = function(node) { // 定义结点
        this.node = node;
        this.weight = getWeight(node);
        this.element.className = node.tagName;
        this.element.innerHTML = node.innerHTML;
    }
}

需要一个根节点包含列表项,这里使用无序列表ul

var rootnode = new Node();
rootnode.element = this.document.createElement('ul');
var prenode = rootnode;

接着是比较节点权重,这里采用递归比较

function compareWeight(curnode, prenode) { // 比较两个节点的权重
    if (curnode.weight >= prenode.weight && prenode.parentnode != null) { // 比较权重,且前一个节点的父节点指针不能为空
        compareWeight(curnode, prenode.parentnode); // 如果当前节点权重大于前一个节点那么则进行向上递归
    } else {
        prenode.element.appendChild(curnode.element); // 如果权重小于前一个节点,那么就当前节点就作为前一个节点的子节点
        curnode.parent = prenode; // 当前节点的父节点指针指向前一个节点
        return; // 递归出口
    }
}

最后遍历所有子节点,封装成带有权重的节点对象,调用递归比较,最后将根节点显示在文档中。

for (var i = 0; i < content.children.length; i++) {
    var node = new Node();
    node.setNode(content.children[i]);
    compareWeight(node, prenode);
    prenode = node;
}
document.body.appendChild(rootnode.element);

整段js代码 所对应的html上下文

var content = this.document.getElementById("content");

function Node() {
    this.node;
    this.element = document.createElement('li');
    this.weight;
    this.parentNode = null;

    function getWeight(node) {
        var weight;
        switch (node.tagName) {
            case 'H1':
                weight = 6;
                break;
            case 'H2':
                weight = 5;
                break;
            case 'H3':
                weight = 4;
                break;
            case 'H4':
                weight = 3;
                break;
            case 'H5':
                weight = 2;
                break;
            case 'H6':
                weight = 1;
                break;
            default:
                weight = 0;
                break;
        }
        return weight;
    }
    this.setNode = function(node) {
        this.node = node;
        this.weight = getWeight(node);
        this.element.className = node.tagName;
        this.element.innerHTML = node.innerHTML;
    }
}

var rootnode = new Node();
rootnode.element = this.document.createElement('ul');
var prenode = rootnode;

function compareWeight(curnode, prenode) {
    if (curnode.weight >= prenode.weight && prenode.parentNode != null) {
        compareWeight(curnode, prenode.parentNode);
    } else {
        prenode.element.appendChild(curnode.element);
        curnode.parentNode = prenode;
        return;
    }
}
for (var i = 0; i < content.children.length; i++) {
    var node = new Node();
    node.setNode(content.children[i]);
    compareWeight(node, prenode);
    prenode = node;
}
document.body.appendChild(rootnode.element);
posted @ 2022-05-12 11:41  maplerain  阅读(136)  评论(0编辑  收藏  举报