博客园高仿more功能

实现虚拟more标签功能

如果用过静态页面生成器写过博客就知道,more功能是比较受欢迎的。

因为要将文章抽象成一种关系数据库的实体,主流后端博客却不支持这种特性,重复的字段无疑会加大数据冗余,对此可以从客户端处理这部分内容,这篇文章记录的自必同学的方案。

Case用例

文章 -> | 获取more标签内容 -> http.get

Code代码

  • http.get

基础库,httpGet请求。

function httpGet(url) {
    return new Promise((next, excp) => {
        const http = new XMLHttpRequest();
        http.open("GET", url, true)
        http.send(null)
        http.onreadystatechange = () => { if (http.readyState === 4) next(http) }
    })
}
  • 获取more标签内容
function getMoreAreaByTag(tmp, section) {
    let idx = tmp.search(section);
    if (idx === -1) return
    tmp = tmp.slice(idx + section.length, -1);
    idx = tmp.search(section);
    if (idx === -1) return
    return tmp.slice(0, idx);
}

tmp是文章数据,section就是定义的分割标签,这里使用br标签作为tag'<br class="more">\n'

  • 文章
function moreTagLoader() {
    let cBPDescs = document.querySelectorAll(".c_b_p_desc")
    if (!cBPDescs || cBPDescs.length < 1) { return }
    cBPDescs.forEach(cBPDesc => {
        if (cBPDesc.getAttribute('t-reload')) { return }
        cBPDesc.setAttribute('t-reload', true)
        fillMoreAreaByTag(cBPDesc) // 涉及到请求 异步去处理
    })
}
async function fillMoreAreaByTag(n) {
    const data = await httpGet(n.firstElementChild.href)
    const moreArea = getMoreAreaByTag(data.responseText, '<br class="more">\n')
    if (moreArea === undefined) { return }
    n.innerHTML = moreArea + n.firstElementChild.outerHTML
}

Review分析

  • 性能
    Regex的算法复杂度是固定的O(n),一般来说,标签的位置会出现在0-10000这个区间,在100ms内认为可接受,可优化无优化必要。思路是减少循环次数,如<!Document>中不会出现目标字符串,减小时间复杂度。
    网络请求,取决于网络环境,正常网络环境下(100kb)可认为误差在100ms内可接受,主流浏览器默认并发请求为6,取决这一特性,建议每页文章数改为5.
    js文件不建议引用,合理的方式应该在页面上直接嵌入,减少网络串行请求,我们一直可以的。

image

Consequent成果

like this, you could write anything between two <br class="more"/> tag.

bold text

italic text

balabala...


  • go on
  • aha
  1. first thing
  2. last thing

image

©zeerbeer

Usage使用

暂不提供使用教程

posted @ 2021-04-02 13:45  ashdyed  阅读(68)  评论(0)    收藏  举报