思路
首发 根据markdown生成的html,二级标题,和三级标题的标志:h2 h3标签提取. 利用锚点加入a标签可以点击跳转到id,实现提取目录跳转。参考 vue doc
实战
本篇教程只提取二级标签,后续会优化,请持续关注
结果
提取标签
获取dom
let content = this.$refs.content;// 提取h2标签let headers = content.querySelectorAll('h2')let each = [].forEachlet str = document.createElement('ul')each.call(headers, function (h) { str.appendChild(self.makeLink(h))})makeLink 函数做的事情,添加a标签返回 字符串domreturn str.innerHTML
makeLink 转换成a标签函数
function makeLink (h) { var link = document.createElement('li') window.arst = h var text = [].slice.call(h.childNodes).map(function (node) { if (node.nodeType === Node.TEXT_NODE) { return node.nodeValue } else if (['CODE', 'SPAN'].indexOf(node.tagName) !== -1) { return node.textContent } else { return '' } }).join('').replace(/\(.*\)$/, '') link.innerHTML = '' + htmlEscape(text) + '' return link}
vuejs 全部
mounted(){ this.sectionContainer = this.getContent() }, methods: { getArticleList() { var params = { id: this.id }; this.$http.get('/articles/desc', { params }).then((res) => { this.article = res.data; }) }, handleCurrentChange(val) { this.page = val; this.getArticleList(); this.$router.replace({ path: `/blog/${val}` }) }, makeLink (h) { var link = document.createElement('li') window.arst = h var text = [].slice.call(h.childNodes).map(function (node) { if (node.nodeType === Node.TEXT_NODE) { return node.nodeValue } else if (['CODE', 'SPAN'].indexOf(node.tagName) !== -1) { return node.textContent } else { return '' } }).join('').replace(/\(.*\)$/, '') link.innerHTML = '' + this.htmlEscape(text) + '' return link }, htmlEscape (text) { return text .replace(/&/g, '&') .replace(/"/g, '"') .replace(/'/g, ''') .replace(//g, '>') }, collectH3s (h) { var h3s = [] var next = h.nextSibling while (next && next.tagName !== 'H2') { if (next.tagName === 'H3') { h3s.push(next) } next = next.nextSibling } return h3s }, getContent(){ var self = this var sectionContainer var each = [].forEach // 获取dom var content = this.$refs.content; // 提取h2标签 var headers = content.querySelectorAll('h2') sectionContainer = document.createElement('ul') each.call(headers, function (h) { sectionContainer.appendChild(self.makeLink(h)) }) return sectionContainer.innerHTML } }
原生js
var sectionContainersectionContainer = document.createElement('ul')var each = [].forEachvar content = document.querySelector('.content')var headers = content.querySelectorAll('h2')each.call(headers, function (h) { sectionContainer.appendChild(makeLink(h)) }) function makeLink (h) { var link = document.createElement('li') window.arst = h var text = [].slice.call(h.childNodes).map(function (node) { if (node.nodeType === Node.TEXT_NODE) { return node.nodeValue } else if (['CODE', 'SPAN'].indexOf(node.tagName) !== -1) { return node.textContent } else { return '' } }).join('').replace(/\(.*\)$/, '') link.innerHTML = '' + htmlEscape(text) + '' return link } function htmlEscape (text) { return text .replace(/&/g, '&') .replace(/"/g, '"') .replace(/'/g, ''') .replace(//g, '>') }