给个人博客网站添加文章搜索功能的关键词检索相关文章

优采云 发布时间: 2021-04-26 04:09

  给个人博客网站添加文章搜索功能的关键词检索相关文章

  概述

  我写了文章来探索如何在个人博客网站中添加文章搜索功能,您可以轻松地通过关键词搜索相关的文章,现在让我们探索另一个功能文章添加目录导航;对于较短的文章,目录的存在影响很小,但是当文章太长时,可以提供预览和跳转的目录结构的预览将变得很重要。继续下来逐步实现它;

  原理样式

  要实现该功能,我们必须首先考虑其原理。目录预览实际上是一条内容,收录当前页面上不同级别标题的组合,并以结构化方式显示。首先,我们可以参考一些网站的做法,例如CSDN博客文章有一个配置目录插件,以下是我的文章之一的目录的预览:

  

  其目录插件是右侧栏上的按钮。将鼠标放在其上时,将显示一个侧栏。内容是当前文章字幕的集合。不同级别的标题对应于不同的缩进级别,单击每个标题将具有相应的页面跳转。这基本上是一种常见且熟悉的目录形式,因此我们将以此为参考来实现;

  获取目录

  在要生成这样的目录之前,当然必须首先获取目录的内容。如前所述,目录的内容是当前文章的所有标题的集合,并且我们知道HTML中与标题相关的标签是h1,h2,h3,h4,h5,h6,因此只需获取他们直接,例如:

  // 获取所有的标签名为 h1 的元素

document.querySelectorAll('h1');

// 获取所有的标签名为 h1 - h6 的元素

document.querySelectorAll('h1, h2, h3, h4, h5, h6');

  检索到的内容是一个收录所有标题节点的数组;下一个问题是考虑如何构造存储,这是易于理解和以后阅读的。所谓结构化的,就是目录本身就是一种树形结构。例如,目录收录多个第一级标题,而某些和标题可能具有多个第二级标题,甚至向下延伸到第三级标题等,类似于以下结构:

  ├─ 一级标题 1

│ └─ 二级标题 1

│ └─ 三级标题 1

│ └─ 四级标题

├─ 一级标题 2

│ └─ 二级标题 1

├─ 一级标题 3

│ ├─ 二级标题 1

│ ├─ 二级标题 2

│ ├─ 二级标题 3

│ │ ├─ 三级标题 1

│ │ ├─ 三级标题 2

... ...

  理论方法是将获得的标题保存在树形结构中,类似于以下内容:

  [{

node: 'h1Node', // 一级标题 1 对应的节点

child: [{

node: 'h2Node', // 二级标题 1

child: [{

node: 'h3Node', // 三级标题 1

child: []

}]

},

{

node: 'h2Node', // 二级标题 2

child: []

}]

},

{

node: 'h1Node', // 一级标题 2

child: [{

node: 'h2Node', // 二级标题 1

child: []

}]

},

{

node: 'h1Node', // 一级标题 3

child: []

}]

  它看起来更复杂并且占用大量空间。它需要递归获取,最后需要递归输出。通常,文章目录收录少量标题,因此暂时不使用此结构。要保存,您可以更改一种简单的思维方式,即,当我们最终生成目录时,我们可以选择逐行逐步输出,即设计以下结构:

  [

'h1Node', // 一级标题 1 对应的元素节点

'h2Node', // 二级标题 1 (隶属于一级标题 1)

'h3Node', // 三级标题 1 (隶属于二级标题 1)

'h2Node', // 二级标题 2 (隶属于一级标题 1)

'h1Node', // 一级标题 2

'h2Node', // 二级标题 1 (隶属于一级标题 2)

'h1Node' // 一级标题 3

]

  因为我们只需要最后输出一个格式化目录列表,即一个一个地输出,所以我们只需要以这种方式存储它,从而减少了占用的空间和复杂性;

  目录生成

  设置最终显示效果,如顶部样本图像所示。根据先前设计的存储结构,遍历数组并逐行打印就足够了;对于不同级别的标题,可以巧妙地使用不同程度的压痕。元素节点的nodeName属性,例如,元素节点对应的nodeName为H1,h2对应于H2,依此类推,我们使用值的最后一个数字并将其乘以固定的缩进值,以便级别增加的title节点也有一个递增的缩进值,最后一个样式部分可以使用padding-left来实现缩进。 js代码的实现思路如下:

  // node 为标题节点,32 是标题级别增加而多缩进的值

node.style.paddingLeft = node.nodeName.slice(-1) * 32 + 'px';

  对于单击标题以跳转到文章中相应标题的位置的功能,实现相对简单,只需设置相应的锚点即可,即title元素需要设置id属性值,然后提供单击标签的href属性。也可以将其设置为此id值,例如:

  一级标题

点我跳转到一级标题</a>

  第三方库的特定实现

  避免重新创建轮子,而将一些基本的格式化样式留给第三方库来解决,这是Materialize库,安装和参考教程转到官方网站:check;

  HTML部分

  具体参考代码和说明如下:

  

apps

</a>

format_list_bulleted

</a>

publish

</a>

目录

Title 1

  Hello World!

  Hello World!

Title 1

  Hello World!

  Hello World!

  Hello World!

  Hello World!

  Hello World!

Title 1

Title 1

  Hello World!

  Hello World!

  Hello World!

Title 2

  Hello World!

  Hello World!

  Hello World!

  Hello World!

  Hello World!

Title 3

  Hello World!

Title 3

  Hello World!

  Hello World!

  Hello World!

  Hello World!

  Hello World!

  Hello World!

  Hello World!

</p>

  CSS部分

  样式部分因人而异,因此您可以自己设计和调整它。以下是参考:

  #category li a:before { /* 添加一个折叠符号,为了好看 */

content: "∟";

position: absolute;

left: 10px;

bottom: 5px;

font-size: 12px;

}

  JavaScript部分

  这部分是核心。对应于上面的HTML和CSS部分,它的实现方式如下:

  // 初始化第三方库的插件

M.AutoInit();

document.addEventListener('DOMContentLoaded', function () {

var elemCategory = document.querySelector('#category');

M.Sidenav.init(elemCategory, {

'edge': 'right' // right 表示在右侧栏显示,left 则表示在左边显示

});

});

var postContent = document.querySelector('#post-content');

if (postContent) { // 存在文章内容

var categories = postContent.querySelectorAll('h1, h2, h3, h4, h5, h6');

if (categories.length > 0) { // 文章存在标题

var category = document.querySelector('#category'),

categoryBtn = document.querySelector('.category-btn');

var li = document.createElement('li'),

a = document.createElement('a');

a.className = 'waves-effect';

// 存在目录则显示目录按钮和侧栏

category.classList.remove('hide');

categoryBtn.classList.remove('hide');

categories.forEach(node => {

// 每次 cloneNode 取代 createElement

// 因为克隆一个元素快于创建一个元素

var _li = li.cloneNode(false),

_a = a.cloneNode(false);

_a.innerText = node.innerText;

// 为标题设置跳转链接

_a.href = '#' + node.id;

_li.appendChild(_a);

// 为不同级别标题应用不同的缩进

_li.style.paddingLeft = node.nodeName.slice(-1) * 32 + 'px';

category.appendChild(_li);

})

}

}

  效果

  最后,我附上了博客网站的一些最终渲染图,欢迎单击以访问^ _ ^

  

  

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线