Hexo博客评论、代码高亮等组件设置、性能优化及SEO

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> Hexo博客评论、代码高亮等组件设置、性能优化及SEO

1 修改主题配色

有自定义的配色还是不错的选择的,所以,我们可以自定义配色。

一般在 /themes/hexo-theme-matery/source/css/matery.css中,搜索 .bg-color 来修改背景颜色,修改标题栏、菜单栏、各种标签背景的颜色,使主题颜色为Material的黑色。感谢Material Design Colours提供的配色方案。

其他的也可以在这个css文件中修改,自己琢磨一下。

2 为你的Hexo加上评论系统-Valine

给个链接:https://blog.csdn.net/blue_zy/article/details/79071414

注意:Valine用在matery主题上有个bug就是第一条评论位置会错位

如下图:

解决办法:

F12开发者模式,控制台定位bug位置,修改参数,调整对应主题源文件参数,得以解决,如下图示:

修改图示

3 SEO 优化

给个链接:https://blog.csdn.net/sunshine940326/article/details/70936988/

4 优化网站加载速度

4.1 优化图片加载

issue问题:

优化网站加载逻辑问题:图片最后加载,加入图片懒加载方法

hexo-lazyload-image的作用原理是讲你博客里面img标签的src属性替换为一个loading image,把真实的图片地址放在data-origin属性下面。然后当你的网页翻到那张图片时(也就是图片在窗口中完全可见时),他会有一段js用data-origin的内容替换src,打到懒加载的目的。

一般情况下懒加载和gallery插件会发生冲突,比如按照我上面所说,最终结果就会变成,可能只有第一张图片在gallery中打开是原图,右翻左翻都会是那张loading image,需要你掌握js,可以修改matery.js里面的内容,甚至可能换一个gallery,比如photosiwpe之类的

解决方法:修改/themes/matery/source/js中的matery.js文件

第103行:


$('#articleContent, #myGallery').lightGallery({
    selector: '.img-item',
    // 启用字幕
    subHtmlSelectorRelative: true,
    showThumbByDefault: false   //这句加上
});

后面加上:


$(document).find('img[data-original]').each(function(){
    $(this).parent().attr("href", $(this).attr("data-original"));
});

再装个插件,https://github.com/Troy-Yang/hexo-lazyload-image
在博客根目录配置.yml文件加入对应字段,如下:


# lazyload configuration  2019.08.23
lazyload:
  enable: true 
  onlypost: false
  loadingImg:     # eg ./images/loading.gif

好了,这样实现了博客网站的图片懒加载。

4.2 Gulp实现代码压缩

Gulp实现代码压缩,以提升网页加载速度。

1 首先我们需要安装Gulp插件和5个功能模块,依次运行下面的两条命令。


npm install gulp -g  #安装gulp
# 安装功能模块
npm install gulp-htmlclean gulp-htmlmin gulp-minify-css gulp-uglify gulp-imagemin --save
# 额外的功能模块
npm install gulp-debug gulp-clean-css gulp-changed gulp-if gulp-plumber gulp-babel babel-preset-es2015 del --save

2 接下来在博客的根目录下新建gulpfile.js文件,并复制下面的内容到文件中。


var gulp = require("gulp");
var debug = require("gulp-debug");
var cleancss = require("gulp-clean-css"); //css压缩组件
var uglify = require("gulp-uglify"); //js压缩组件
var htmlmin = require("gulp-htmlmin"); //html压缩组件
var htmlclean = require("gulp-htmlclean"); //html清理组件
var imagemin = require("gulp-imagemin"); //图片压缩组件
var changed = require("gulp-changed"); //文件更改校验组件
var gulpif = require("gulp-if"); //任务 帮助调用组件
var plumber = require("gulp-plumber"); //容错组件(发生错误不跳出任务,并报出错误内容)
var isScriptAll = true; //是否处理所有文件,(true|处理所有文件)(false|只处理有更改的文件)
var isDebug = true; //是否调试显示 编译通过的文件
var gulpBabel = require("gulp-babel");
var es2015Preset = require("babel-preset-es2015");
var del = require("del");
var Hexo = require("hexo");
var hexo = new Hexo(process.cwd(), {}); // 初始化一个hexo对象

// 清除public文件夹
gulp.task("clean", function() {
  return del(["public/**/*"]);
});

// 下面几个跟hexo有关的操作,主要通过hexo.call()去执行,注意return
// 创建静态页面 (等同 hexo generate)
gulp.task("generate", function() {
  return hexo.init().then(function() {
    return hexo
      .call("generate", {
        watch: false
      })
      .then(function() {
        return hexo.exit();
      })
      .catch(function(err) {
        return hexo.exit(err);
      });
  });
});

// 启动Hexo服务器
gulp.task("server", function() {
  return hexo
    .init()
    .then(function() {
      return hexo.call("server", {});
    })
    .catch(function(err) {
      console.log(err);
    });
});

// 部署到服务器
gulp.task("deploy", function() {
  return hexo.init().then(function() {
    return hexo
      .call("deploy", {
        watch: false
      })
      .then(function() {
        return hexo.exit();
      })
      .catch(function(err) {
        return hexo.exit(err);
      });
  });
});

// 压缩public目录下的js文件
gulp.task("compressJs", function() {
  return gulp
    .src(["./public/**/*.js", "!./public/libs/**"]) //排除的js
    .pipe(gulpif(!isScriptAll, changed("./public")))
    .pipe(gulpif(isDebug, debug({ title: "Compress JS:" })))
    .pipe(plumber())
    .pipe(
      gulpBabel({
        presets: [es2015Preset] // es5检查机制
      })
    )
    .pipe(uglify()) //调用压缩组件方法uglify(),对合并的文件进行压缩
    .pipe(gulp.dest("./public")); //输出到目标目录
});

// 压缩public目录下的css文件
gulp.task("compressCss", function() {
  var option = {
    rebase: false,
    //advanced: true,               //类型:Boolean 默认:true [是否开启高级优化(合并选择器等)]
    compatibility: "ie7" //保留ie7及以下兼容写法 类型:String 默认:''or'*' [启用兼容模式; 'ie7':IE7兼容模式,'ie8':IE8兼容模式,'*':IE9+兼容模式]
    //keepBreaks: true,             //类型:Boolean 默认:false [是否保留换行]
    //keepSpecialComments: '*'      //保留所有特殊前缀 当你用autoprefixer生成的浏览器前缀,如果不加这个参数,有可能将会删除你的部分前缀
  };
  return gulp
    .src(["./public/**/*.css", "!./public/**/*.min.css"]) //排除的css
    .pipe(gulpif(!isScriptAll, changed("./public")))
    .pipe(gulpif(isDebug, debug({ title: "Compress CSS:" })))
    .pipe(plumber())
    .pipe(cleancss(option))
    .pipe(gulp.dest("./public"));
});

// 压缩public目录下的html文件
gulp.task("compressHtml", function() {
  var cleanOptions = {
    protect: /<\!--%fooTemplate\b.*?%-->/g, //忽略处理
    unprotect: /<script [^>]*\btype="text\/x-handlebars-template"[\s\S]+?<\/script>/gi //特殊处理
  };
  var minOption = {
    collapseWhitespace: true, //压缩HTML
    collapseBooleanAttributes: true, //省略布尔属性的值  <input checked="true"/> ==> <input />
    removeEmptyAttributes: true, //删除所有空格作属性值    <input id="" /> ==> <input />
    removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
    removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css"
    removeComments: true, //清除HTML注释
    minifyJS: true, //压缩页面JS
    minifyCSS: true, //压缩页面CSS
    minifyURLs: true //替换页面URL
  };
  return gulp
    .src("./public/**/*.html")
    .pipe(gulpif(isDebug, debug({ title: "Compress HTML:" })))
    .pipe(plumber())
    .pipe(htmlclean(cleanOptions))
    .pipe(htmlmin(minOption))
    .pipe(gulp.dest("./public"));
});

// 压缩 public/uploads 目录内图片
gulp.task("compressImage", function() {
  var option = {
    optimizationLevel: 5, //类型:Number  默认:3  取值范围:0-7(优化等级)
    progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片
    interlaced: false, //类型:Boolean 默认:false 隔行扫描gif进行渲染
    multipass: false //类型:Boolean 默认:false 多次优化svg直到完全优化
  };
  return gulp
    .src("./public/medias/**/*.*")
    .pipe(gulpif(!isScriptAll, changed("./public/medias")))
    .pipe(gulpif(isDebug, debug({ title: "Compress Images:" })))
    .pipe(plumber())
    .pipe(imagemin(option))
    .pipe(gulp.dest("./public"));
});
// 执行顺序: 清除public目录 -> 产生原始博客内容 -> 执行压缩混淆 -> 部署到服务器
gulp.task(
  "build",
  gulp.series(
    "clean",
    "generate",
    "compressHtml",
    "compressCss",
    "compressJs",
    "compressImage",
    gulp.parallel("deploy")
  )
);

// 默认任务
gulp.task(
  "default",
  gulp.series(
    "clean",
    "generate",
    gulp.parallel("compressHtml", "compressCss", "compressImage", "compressJs")
  )
);
//Gulp4最大的一个改变就是gulp.task函数现在只支持两个参数,分别是任务名和运行任务的函数

3 最后 hexo clean && hexo g && gulp && hexo d 就可以了。

注意,很可能你会运行到第三步,也就是运行gulp压缩命令时会报错。

那是因为gulp安装的本地版本和hexo自带的版本不对应导致,第三步gulp压缩可以用下面命令强制使用本地版本:


node ./node_modules/gulp/bin/gulp.js

4.3 Github & Coding Pages 双部署

Github & Coding Pages 双部署,对国内,国外用户进行分流访问,以提升网站的访问速度。

Github Pages 的部署前面已经说了,这里就讲一讲 Coding Pages 如何部署.其实与 Github Pages 也类似,先到coding官网注册,创建一个与用户名同名的仓库,添加仓库地址到配置文件中,在根目录_config.yml对应地方添加如下:


# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
- type: git                                                      # 设置发布类型,如git     
  repo: 
    github: git@github.com:OUYANGSIHAI/OUYANGSIHAI.github.io.git   # 设置repository对应的链接
    coding: git@e.coding.net:ouyangsihai/sihaiblog.git
  branch: master                                                 # 设置提交到的分支
  message: Site updated at {{ now("YYYY-MM-DD HH:mm:ss") }}      # 设置我们提交的信息
- type: baidu_url_submitter

把本地生成 SSH 公匙添加到 Coding 这一步看我前面的教程,原理类似.

然后 hexo clean && hexo g && hexo d 部署上去就是了.

当然,部署上去后,你需要开启 page 服务.

你可以在 pages 设置里面自定义域名,区域名解析控制台,添加两条 CNAME 记录,将域名指向 RepoName.coding.me就可以的,申请 ssl 证书,强制开启https

可能遇到的问题:

  • coding pages 申请ssl 证书总是提示:错误!

这里提一句,如果你是github pages 和 coding pages双部署,用同一个域名的话,可以将xxx.github.io 解析成 境外, xxx.coding.me 解析成 默认,这个时候如果你之前就申请过 ssl 证书的话,再在 coding 里面申请 ssl证书会一直提示 失败,解决办法:

先去域名解析控制台,将境外解析的两条 CNAME 记录 暂停,过个五六分钟,回到 coding 点击申请 ssl,很快就会提示,申请成功!

刚好我过程中遇到了这个问题,所以把它记下来,方便后面的小伙伴看到.

5 代码高亮

由于 Hexo 自带的代码高亮主题显示不好看,所以主题中使用到了 hexo-prism-plugin 的 Hexo 插件来做代码高亮,安装命令如下:


npm i -S hexo-prism-plugin

然后,修改 Hexo 根目录下 _config.yml 文件中 highlight.enable 的值为 false,并新增 prism 插件相关的配置,主要配置如下:


highlight:
  enable: false

prism_plugin:
  mode: 'preprocess'    # realtime/preprocess
  theme: 'tomorrow'
  line_number: false    # default false
  custom_css:

做了除此设置之外,还有一个很大的问题,就是写代码块的时候,并不会自动的识别是哪种语言,还需要在代码前面标记是哪种语言,所以,非常的麻烦,未来解决这个问题还问了一个同用这个主题的网友,非常感谢他的热心帮助。

解决方法

在这个路径在找到这个文件


/**
 * Code transform for prism plugin.
 * @param {Object} data
 * @return {Object}
 */
function PrismPlugin(data) {
  // Patch for caption support
  if (captionRegex.test(data.content)) {
    // Attempt to parse the code
    data.content = data.content.replace(captionRegex, (origin, lang, caption, code) => {
      if (!lang || !caption || !code) return origin;
      return `<figcaption>${caption}</figcaption><pre><code class="${lang}">${code}</code></pre>`;
    })
  }
  //============= 
   var myflag=true
//===================
  data.content = data.content.replace(regex, (origin, lang, code) => {
    const lineNumbers = line_number ? 'line-numbers' : '';
    const startTag = `<pre class="${lineNumbers} language-${lang}"><code class="language-${lang}">`;
    const endTag = `</code></pre>`;
 
    code = unescape(code); 
    let parsedCode = '';

    if (Prism.languages[lang]) {
      parsedCode = Prism.highlight(code, Prism.languages[lang]);
    } else {
      parsedCode = code;
    }
    if (line_number) {
      const match = parsedCode.match(/\n(?!$)/g);
      const linesNum = match ? match.length + 1 : 1;
      let lines = new Array(linesNum + 1);
      lines = lines.join('<span></span>');
      const startLine = '<span aria-hidden="true" class="line-numbers-rows">';
      const endLine = '</span>';
      parsedCode += startLine + lines + endLine;
    }
    myflag=false
    return startTag + parsedCode + endTag;
  });

//================================================================================================
   if(myflag){
            data.content=data.content.replace(/<code>/igm,'<code class="c">\n')  //c 改成 java 即可
            data.content = data.content.replace(regex, (origin, lang, code) => {
            const lineNumbers = line_number ? 'line-numbers' : '';
            const startTag = `<pre class="${lineNumbers} language-${lang}"><code class="language-${lang}">`;
            const endTag = `</code></pre>`;
            code = unescape(code); 
            let parsedCode = '';

            if (Prism.languages[lang]) {
              parsedCode = Prism.highlight(code, Prism.languages[lang]);
            } else {
              parsedCode = code;
            }
            if (line_number) {
              const match = parsedCode.match(/\n(?!$)/g);
              const linesNum = match ? match.length + 1 : 1;
              let lines = new Array(linesNum + 1);
              lines = lines.join('<span></span>');
              const startLine = '<span aria-hidden="true" class="line-numbers-rows">';
              const endLine = '</span>';
              parsedCode += startLine + lines + endLine;
            }
            return startTag + parsedCode + endTag;
          });
   }
//================================================================================================

  return data;
}

/**
 * Copy asset to hexo public folder.
 */
function copyAssets() {
  const assets = [{
    path: `css/${prismThemeFileName}`,
    data: () => fs.createReadStream(prismThemeFilePath)
  }];

  // If line_number is enabled in plugin config add the corresponding stylesheet
  if (line_number) {
    assets.push({
      path: 'css/prism-line-numbers.css',
      data: () => fs.createReadStream(path.join(prismLineNumbersPluginDir, 'prism-line-numbers.css'))
    });
  }

  // If prism plugin config mode is realtime include prism.js and line-numbers.js
  if (mode === 'realtime') {
    assets.push({
      path: 'js/prism.js',
      data: () => fs.createReadStream(prismMainFile)
    });
    if (line_number) {
      assets.push({
        path: 'js/prism-line-numbers.min.js',
        data: () => fs.createReadStream(path.join(prismLineNumbersPluginDir, 'prism-line-numbers.min.js'))
      });
    }
  }

  return assets;
}

/**
 * Injects code to html for importing assets.
 * @param {String} code
 * @param {Object} data
 */

如果你不是Java,想改成其他语言,修改上面代码的这部分即可。

给代码块开启行号

我们在配置文件.yml中找到prism_plugin配置项line_number: false(# default false)改为true,开启行号,但是在我们这个matery主题中中是无效的,有bug需要改一下matery.css样式参数,在第95行位置将:


pre {
    padding: 1.5rem !important;
    margin: 1rem 0 !important;
    background: #272822;
    overflow: auto;
    border-radius: 0.35rem;
    tab-size: 4;
}

改为:


pre {
    padding: 1.5rem 1.5rem 1.5rem 3.3rem !important;
    margin: 1rem 0 !important;
    background: #272822;
    overflow: auto;
    border-radius: 0.35rem;
    tab-size: 4;
}

注释掉紧接着的code代码块里面的font-size项,如下:


code {
    padding: 1px 5px;
    font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier, monospace;
    /*font-size: 0.91rem;*/
    color: #e96900;
    background-color: #f8f8f8;
    border-radius: 2px;
}

好了这下可以显示行号了。

6 修改页面底部

找到这个文件

修改成以下内容


本站由&copy;<a href="https://blog.ouyangsihai.cn" target="_blank"> 欧阳思海 </a>维护.

7 图片压缩

参考文章:https://www.zrahh.com/archives/269.html

8 代码块优化

1. 安装代码块插件


npm i -S hexo-prism-plugin

2. Hexo根目录配置

打开Hexo根目录的配置文件 _config.yml,修改并添加如下代码


highlight:
  enable: false # 关闭原有的高亮代码

# 添加prism_plugin配置项
prism_plugin:
  mode: 'preprocess'    # realtime/preprocess
  theme: 'tomorrow'
  line_number: true    # default false
  custom_css:

3. Matery主题根目录

打开Matery主题的配置文件 themes\matery\_config.yml,添加如下代码


code:
  lang: true # 代码块是否显示名称
  copy: true # 代码块是否可复制
  shrink: true # 代码块是否可以收缩
  break: false # 代码是否折行

4. 代码块CSS优化

打开 themes\source\css\matery.css,大概在100到200行左右,修改代码块CSS样式如下


pre {
    padding: 1.5rem 1.5rem 1.5rem 3.3rem !important;
    margin: 1rem 0 !important;
    background: #272822;
    overflow: auto;
    border-radius: 0.35rem;
    tab-size: 4;
}
.code-area::after {
    content: " ";
    position: absolute;
    border-radius: 50%;
    background: #ff5f56;
    width: 12px;
    height: 12px;
    top: 0;
    left: 12px;
    margin-top: 12px;
    -webkit-box-shadow: 20px 0 #ffbd2e, 40px 0 #27c93f;
    box-shadow: 20px 0 #ffbd2e, 40px 0 #27c93f;
}
code {
    padding: 1px 5px;
    top: 13px !important;
    font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier, monospace;
    font-size: 0.91rem;
    color: #e96900;
    background-color: #f8f8f8;
    border-radius: 2px;
}
.code_copy {
    position: absolute;
    top: 0.7rem;
    right: 25px;
    z-index: 1;
    filter: invert(50%);
    cursor: pointer;
}
.codecopy_notice {
    position: absolute;
    top: 0.7rem;
    right: 6px;
    z-index: 1;
    filter: invert(50%);
    opacity: 0;
}
.code_lang {
    position: absolute;
    top: 1.2rem;
    right: 46px;
    line-height: 0;
    font-weight: bold;
    font-family: normal;
    z-index: 1;
    filter: invert(50%);
    cursor: pointer;
}

.code-expand {
    position: absolute;
    top: 4px;
    right: 0px;
    filter: invert(50%);
    padding: 7px;
    z-index: 999 !important;
    cursor: pointer;
    transition: all .3s;
    transform: rotate(0deg);
}

.code-closed .code-expand {
    transform: rotate(-180deg) !important;
    transition: all .3s;
}

.code-closed pre::before {
    height: 0px;
}

pre code {
    padding: 0;
    color: #e8eaf6;
    background-color: #272822;
}

pre[class*="language-"] {
    padding: 1.2em;
    margin: .5em 0;
}

code[class*="language-"],
pre[class*="language-"] {
    color: #e8eaf6;
    white-space: pre-wrap !important;
}

.line-numbers-rows {
    border-right-width: 0px !important;
}

.line-numbers {
    padding: 1.5rem 1.5rem 1.5rem 3.2rem !important;
    margin: 1rem 0 !important;
    background: #272822;
    overflow: auto;
    border-radius: 0.35rem;
    tab-size: 4;
}

5. 文章代码块添加

打开 themes\matery\layout\_partial\post-detail.ejs,添加如下代码


<!-- 代码块功能依赖 -->
<script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeBlockFunction.js') %>"></script>

<!-- 代码语言 -->
<% if (theme.code.lang) { %>
<script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeLang.js') %>"></script>
<% } %>

<!-- 代码块复制 -->
<% if (theme.code.copy) { %>
<script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeCopy.js') %>"></script>
<% } %>

<!-- 代码块收缩 -->
<% if (theme.code.shrink) { %>
<script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeShrink.js') %>"></script>
<% } %>

<!-- 代码块折行 -->
<% if (!theme.code.break) { %>
<style type="text/css"> code[class*="language-"], pre[class*="language-"] { white-space: pre !important; } </style>
<% } %>

6. 代码块JS添加

打开目录 themes\matery\source\libs,新建一个名字为 codeBlock的目录,然后打开该目录。

themes\matery\source\libs\codeBlock目录下新建 codeBlockFunction.js文件,并添加如下代码


// 代码块功能依赖
$(function () {
    $('pre').wrap('<div class="code-area" style="position: relative"></div>');
});

themes\matery\source\libs\codeBlock目录下新建 codeCopy.js文件,并添加如下代码


// 代码块一键复制
$(function () {
    var $copyIcon = $('<i class="fa fa-files-o code_copy" title="复制代码" aria-hidden="true"></i>')
    var $notice = $('<div class="codecopy_notice"></div>')
    $('.code-area').prepend($copyIcon)
    $('.code-area').prepend($notice)
    // “复制成功”字出现
    function copy(text, ctx) {
        if (document.queryCommandSupported && document.queryCommandSupported('copy')) {
            try {
                document.execCommand('copy') // Security exception may be thrown by some browsers.
                $(ctx).prev('.codecopy_notice')
                    .text("复制成功")
                    .animate({
                        opacity: 1,
                        top: 30
                    }, 450, function () {
                        setTimeout(function () {
                            $(ctx).prev('.codecopy_notice').animate({
                                opacity: 0,
                                top: 0
                            }, 650)
                        }, 400)
                    })
            } catch (ex) {
                $(ctx).prev('.codecopy_notice')
                    .text("复制失败")
                    .animate({
                        opacity: 1,
                        top: 30
                    }, 650, function () {
                        setTimeout(function () {
                            $(ctx).prev('.codecopy_notice').animate({
                                opacity: 0,
                                top: 0
                            }, 650)
                        }, 400)
                    })
                return false
            }
        } else {
            $(ctx).prev('.codecopy_notice').text("浏览器不支持复制")
        }
    }
    // 复制
    $('.code-area .fa-files-o').on('click', function () {
        var selection = window.getSelection()
        var range = document.createRange()
        range.selectNodeContents($(this).siblings('pre').find('code')[0])
        selection.removeAllRanges()
        selection.addRange(range)
        var text = selection.toString()
        copy(text, this)
        selection.removeAllRanges()
    })
});

themes\matery\source\libs\codeBlock目录下新建 codeLang.js文件,并添加如下代码


// 代码块语言识别
$(function () {
  var $highlight_lang = $('<div class="code_lang" title="代码语言"></div>');

  $('pre').before($highlight_lang);
  $('pre').each(function () {
    var code_language = $(this).attr('class');

    if (!code_language) {
      return true;
    };
    var lang_name = code_language.replace("line-numbers", "").trim().replace("language-", "").trim();

    // 首字母大写
    // lang_name = lang_name.slice(0, 1).toUpperCase() + lang_name.slice(1);

    $(this).siblings(".code_lang").text(lang_name);
  });
});

themes\matery\source\libs\codeBlock目录下新建 codeShrink.js文件,并添加如下代码


// 代码块收缩
$(function () {
  var $code_expand = $('<i class="fa fa-angle-down code-expand" aria-hidden="true"></i>');

  $('.code-area').prepend($code_expand);
  $('.code-expand').on('click', function () {
    if ($(this).parent().hasClass('code-closed')) {
      $(this).siblings('pre').find('code').show();
      $(this).parent().removeClass('code-closed');
    } else {
      $(this).siblings('pre').find('code').hide();
      $(this).parent().addClass('code-closed');
    }
  });
});

7. 解决代码块复制内容不换行问题

Matery主题在开启复制版权且添加了版权信息后,会导致复制的所有内容换行失效,以下将解决这个问题。

themes\matery\layout\_partial\post-detail.ejs文件中,大约在222行左右找到 selection.getRangeAt(0).commonAncestorContainer.nodeName,将原先 if条件中的的 PRE修改为 CODE即可。


if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'CODE') {
    newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>";
}

至此,代码块的优化已经全部完成。

来源: Luckysec
文章作者: Luckysec
文章链接: http://luckyzmj.cn/posts/1b9a9e28.html
本文章著作权归作者所有,任何形式的转载都请注明出处。

9 一键推送到各个搜索引擎

https://cjh0613.com/20200603HexoSubmitUrlsToSearchEngine.html

9 更多详情查看

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> Hexo博客评论、代码高亮等组件设置、性能优化及SEO


 上一篇
面试官问你B树和B+树,就把这篇文章丢给他 面试官问你B树和B+树,就把这篇文章丢给他
原文链接:面试官问你B树和B+树,就把这篇文章丢给他 1 B树在介绍B+树之前, 先简单的介绍一下B树,这两种数据结构既有相似之处,也有他们的区别,最后,我们也会对比一下这两种数据结构的区别。 1.1 B树概念B树也称B-树,它是一颗多
下一篇 
InnoDB与MyISAM等存储引擎对比 InnoDB与MyISAM等存储引擎对比
InnoDB存储引擎介绍InnoDB引擎是Mysql的默认的存储引擎,他有很多自己的特性,下面一一列举。 支持事务,InnoDB存储引擎主要就是为了在线事务处理(OLTP)的应用而设计的。 行锁设计,支持外键,非锁定读。 支持多版本的并发