博客改装第一步,随机子标题


# 前言

这篇文章算是一个事后记录吧,当时做的时候没有同步记录过程

我记得我是看了谁的博客才有的这个想法,但是当时实现这个功能的时候忘记保存链接了...

# 成品效果

# 涉及文件

- /themes/landscape-plus/layout/_partial/header.ejs
- _config.yml

# 简要思路

在生成博客子标题时,JS 脚本以特定字符切割设置里的 subtitle 字符串,
同时产生随机数随机选择一条进行显示

# 详细步骤

(其实就两个地方有小改动而已...)

原有代码(第 8 行开始):

<% if (theme.subtitle){ %>
  <h2 id="subtitle-wrap">
    <a href="<%- url_for() %>" id="subtitle"><%= theme.subtitle %></a>
  </h2>
<% } %>

可以看见生成出来的子标题即为设置中的字段。

为了达到随机子标题的效果,我们需要在设置中想办法填写所有可能的值,
并在这里随机显示一个。

由于 Hexo 是静态博客,不能实现服务端随机,故我的实现方法为:博客生成一个数组嵌入 HTML,
加载页面时随机抽取一个进行显示。

在博客设置中按如下方式填写:

subtitle: |-
  Someone is climbing.
  Someone is learning.
  Someone is waiting.

关于 yaml 多行字符串,可以参考这里

更改后的代码如下:

有关 EJS 语法可以参考这里

# 添加动态打字效果

动态打字效果可以使用 typed.js 完成。

首先在页面内引入 typed.js (在 header.ejs 中,subtitle 上方添加)

<% if (theme.subtitle){ %>
<h2 id="subtitle-wrap">
    <!-- 这里不硬编码数据,改用下面的 Javascript 生成并填写 -->
    <a href="<%- url_for() %>" id="subtitle"></a>
</h2>
<!-- Random subtitle -->
<script>
    (function () {
    var subtitles = [
        <% for(var i = 0, s = theme.subtitle.split("\n");
        i < s.length; ++i) { %>
        "<%- s[i] %>",
        <% } %>
    ];
    document.getElementById("subtitle").innerText =
        subtitles[Math.floor(Math.random() * subtitles.length)];
    })();
</script>
<% } %>
<!-- CDN 模式 -->
<script src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11"></script>
<!-- 或者下载到 source 文件夹内(根目录或主题内均可行),然后引入本地文件 -->
<script src="/js/typed.js"></script>

然后简单调一下设置就好啦,把上一节的 js 代码更换为下方所示即可

有关 Typed.js 的更多用法,可参考这里的 Demo文档.

# 更新日志

  • 2020-04-12
    • 修复转义字符的问题
    • 添加动态效果
  • 2020-04-11
    • 第一版上线
<script>
  (function () {
    var typed = new Typed("#subtitle", {
      typeSpeed: 40,  // 打字时的 interval
      backSpeed: 10,  // 删除时的 interval
      backDelay: 2000,  // 打完一行之后的 timeout
      startDelay: 500,  // 删完一行之后的 timeout
      shuffle: true,  // 打乱 strings 数组的元素顺序
      loop: true, // 不断循环
      strings: [  // 字符串源
        <% for(var i = 0, s = theme.subtitle.split("\n");
          i < s.length; ++i) {
            /* ignore the last element which is a null string */ %>
        "<%= s[i] %>",<% } %>]});
  })();
</script>