突发奇想,对于markdown里的todolist,我想做一个进度条。所以就开始尝试。

首先打开我的博客,F12看我的markdown里todolist的渲染结果,也就是一个html页面的源代码,看到的todolist渲染结果大概是这样的。

    <ul class="task-list" id="l1">
        <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />《幸福课》9
            积极情绪</li>
        <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />《幸福课》10
            如何去改变</li>
        <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />《幸福课》11
            养成良好习惯</li>
        <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"
                checked="checked" />10 MySQL为什么有时候会选错索引?</li>
        <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"
                checked="checked" />11 怎么给字符串字段加索引?</li>

    </ul>

所以我要做的是

  1. document.querySelectorAll('ul')来获取所有的ul,
  2. 对于每个ul,遍历它的子节点。统计checked=”checked”的个数记为checked
  3. 判断checked个数是否大于0,不大于则直接跳出不处理。(因为ul可能是其他的ul,不一定包含checkbox,这里偷懒了,直接checked==0则返回)
  4. 得到数据之后创建progress元素。
  5. 把progress元素插入到ul之前。

也就是下面的代码,把下面的代码插入.md中,就可以实现给todo list加进度条了,哈哈哈。

很显然,对于jekyll框架来说,不需要每个.md底下都加,直接在layouts文件夹里找到渲染文章的那个html,往那里面加就好了。

这篇文章的markdownw文件里是有加下面这段代码的,所以我随便写几个todolist,在界面上应该能看到进度条。(同时因为我的博客渲染的时候也会插入相同的代码,所以这篇文章会看到两个进度条,问题不大。

<script>
    function getProcess(ul) {
        let total = 0, checked = 0;
        var childs = ul.childNodes;
        for (let i = 0; i < ul.childNodes.length; i++) {
            var item = ul.childNodes[i]
            if (item.childNodes.length > 0) {
                // console.log(1)
                // console.log(item.childNodes[0].checked)
                if (item.childNodes[0].checked) {
                    checked++
                }
                total++
            }
        }
        return [checked, total]
    }

    function createProgressDiv(max, value) {
        let sp1 = document.createElement("div");
        let progress = document.createElement("progress")
        progress.value = value
        progress.max = max
        sp1.appendChild(progress)
        let text = ` ${value}/${max}`
        let progressInNumber = document.createTextNode(text)
        sp1.appendChild(progressInNumber)
        return sp1
    }

    function insertBeforeUL(ul) {
        const [checked, total] = getProcess(ul);
        if (checked == 0) {
            return;
        }
        let progressDiv = createProgressDiv(total, checked)
        let parentDiv = ul.parentNode;
        parentDiv.insertBefore(progressDiv, ul);
    }

    var ulList = document.querySelectorAll('ul')
 
    for (let i = 0; i < ulList.length; i++) {
       insertBeforeUL(ulList[i])
    }
</script>

示例

1

  • 1
  • 2
  • 3
  • 4
  • 5

2

  • 1
  • 2
  • 3
  • 4
  • 5