更新 pure-highlightjs 插件,实现显示代码行号、鼠标悬浮行和被标记行高亮

一、JS 源码

JS 源码如下:

(function(win, doc) {
  var getById = function(el) {
    return doc.getElementById(el);
  };
  
  // 行号和高亮行处理 
  var hljs = {
    $code: doc.querySelectorAll('pre code'),
    hasClass: function (ele, cls) {
      return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
    },
    addClass: function (ele, cls) { 
      if (!hljs.hasClass(ele, cls)) {
        ele.className += ' ' + cls;
      }
    },
    removeClass: function (ele, cls) {
      if (hljs.hasClass(ele,cls)) {
        ele.className = ele.className.replace(new RegExp('(\\s|^)' + cls + '(\\s|$)'),' ');
      }
    }
  };

  /**
   * 使用数据生成hash
   *
   * @param  {Object} data 数据
   * @param {number} data.index 代码块位置, 以1开始
   * @param {number} data.start 行号开始
   * @param {number} data.end 行号结束
   *
   * @return {string}
   */
  hljs.stringHash = function (data) {
    var hash = '';
    if (data.index >= 1) {
      hash += data.index + '-';
    }
    hash += 'L' + data.start;
    if (data.end && data.end > data.start) {
      hash += '-' + 'L' + data.end;
    }
    return hash;
  };

  /**
   * 解析hash为数据
   *
   * @return {Object} {index: 当前代码块位置, 以1开始,  start: 行号开始,  end: 结束位置}
   */
  hljs.parseHash = function () {
    var parse = location.hash.substr(1).match(/((\d+)-)?L(\d+)(-L(\d+))?/);

    if (!parse) {
      return null;
    }

    return {
      index: parseInt(parse[2], 10) || 1,
      start: parseInt(parse[3], 10) || 1,
      end: parseInt(parse[5], 10) || parseInt(parse[3], 10) || 1
    }
  };

  /**
   * 标记行颜色并跳转
   */
  hljs.mark = function (go) {
    var hash = hljs.parseHash();
    if (!hash || !hljs.$code || !hljs.$code[hash.index - 1]) {
      return;
    }

    var $li = hljs.$code[hash.index - 1].querySelectorAll('li');
    for (var i = hash.start - 1; i < hash.end; i++) {
      if ($li[i]) {
        hljs.addClass($li[i], 'mark');
      }
    }
    if (go && $li && $li[0]) {
      setTimeout(function () {
        window.scrollTo(0, getRect($li[0]).top - 50);
      });
    }
  };

  /**
   * 移除所有高亮行号
   */
  hljs.removeMark = function () {
    doc.querySelectorAll('pre code li.mark').forEach(function (elem) {
      hljs.removeClass(elem, 'mark');
    });
  };

  /**
   * 初始化
   */
  hljs.init = function () {
    var $code = hljs.$code;
    if ($code && $code.length) {
      $code.forEach(function (elem, i) {
        // 输出行号, -1是为了让最后一个换行忽略
        var lines = elem.innerHTML.split(/\n/).slice(0, -1);
        var html = lines.map(function (item, index) {
          return '<li><span class="line-num" data-line="' + (index + 1) + '"></span>' + item + '</li>';
        }).join('');
        html = '<ul>' + html + '</ul>';

        elem.innerHTML = html;

        hljs.addClass(elem, 'code-with-line-number');

        // 绑定点击高亮行事件
        elem.addEventListener('click', function (event) {
          // 小小的委托
          if (!event.target || !hljs.hasClass(event.target, 'line-num')) {
            return;
          }

          // 如果是区间
          if (event.shiftKey) {
            var hash = hljs.parseHash();
            hash.newIndex = i + 1;
            hash.current = event.target.getAttribute('data-line');
            if (hash.index !== hash.newIndex - 0) {
              hash.index = hash.newIndex;
              hash.start = hash.current;
              hash.end = 0;
            }
            else {
              if (hash.current > hash.start) {
                hash.end = hash.current;
              }
              else {
                hash.end = hash.start;
                hash.start = hash.current;
              }
            }
            location.hash = hljs.stringHash(hash);
          }
          else {
            location.hash = hljs.stringHash({
              index: i + 1,
              start: event.target.getAttribute('data-line')
            });
          }
        });
      });
    }
  };

  hljs.init();
  win.addEventListener('load', function() {
    hljs.mark(true);
  });
  win.addEventListener('hashchange', function () {
    hljs.removeMark();
    hljs.mark();
  });

})(window, document);

 

二、CSS 源码

CSS 源码如下:

/* 文章内代码行号高亮 */
.code-with-line-number > ul {
  list-style: decimal;
  margin: 0;
  margin-left: 40px;
  padding: 0;
}
.code-with-line-number li {
  list-style: decimal-leading-zero;
  border-left: 1px solid #ddd;
  padding-left: 2px;
  position: relative;
}
.code-with-line-number li.mark {
  /* 被标记行高亮背景色 需根据代码高亮主题进行修改 */
  background-color: #423c36 !important;
}
.code-with-line-number li:hover {
  /* 鼠标悬浮行高亮背景色 需根据代码高亮主题进行修改 */
  background-color: #607d8b4d !important;
}
.code-with-line-number .line-num {
  width: 40px;
  position: absolute;
  top: 0;
  height: 100%;
  left: -40px;
  cursor: pointer;
}

/*下面是覆盖默认样式, 为了防闪动*/
pre {
  border-left: none;
  padding: 0;  
}

其中需要自定义修改的地方已用注释标出。为了简化设置的步骤,我将插件源码做了修改,更新后的插件可以在插件设置中可视化地设置鼠标悬浮行高亮背景色和被标记行高亮背景色。如图:

插件设置界面

更新后的插件项目地址为:Pure-Highlightjs

下载地址为:https://github.com/sunriseydy/Pure-Highlightjs/releases

参考链接

给博客的highlight.js添加行号和行号高亮


版权说明:
作品 sunriseydy 采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
文章内容如未说明均为原创,欢迎转载,但请注明原作者(sunriseydy)和原文链接(https://blog.sunriseydy.top/technology/server-blog/wordpress/pure-highlightjs-with-line-number/)
部分来自互联网的文章,如有侵权,请联系我,24小时内删除,谢谢

手机打开扫一扫即可访问本页面

感谢您的支持,SunriseYDY 会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

日出一点一 | 在探索的路上永不止步

分享到微博 分享到QQ 微信赞赏 在手机上阅读 点赞 1

页面: 1 2

“更新 pure-highlightjs 插件,实现显示代码行号、鼠标悬浮行和被标记行高亮”的13个回复

  1. 风君子

    你好,为啥我再github下载的最新版安装后还是不显示行号,wp4.9.8版本
    能麻烦给看一下吗?https://www.fengjunzi.com/blog-1385.html
    感觉这个插件比较方便

    • @风君子 将 line-number.css 文件中 “.code-with-line-number li” 的样式: “list-style” 后面加一个 ” !important” 就行了,即: “list-style: decimal-leading-zero !important;”。原因嘛,就是你的其他CSS样式将它变成了”disc”。

  2. line-number.js文件丢失了

    • @iBoy 已将链接改为 GitHub 下载链接,谢谢提醒。

      • @日出1.1 主题可以把原版插件的集成进去吗?和我的博客(https://iboy.ooo)风格不匹配

        • @iBoy 你可以在设置里更改主题呀,v2版用的就是原版的主题,只不过行号和当前行高亮颜色要在line-number.css文件中手动修改以适配当前使用的主题,我记得在文章中有写到。v3版插件用的是Prism的主题,同样可以在后台设置里更改,如果主题不适合可以去Prism的官网下载其他主题。

  3. Mactor

    博主你好 我发现cpp的高亮无法正常显示

    • @Mactor 无法正常显示是什么样子?没有高亮还是高亮显示不正确?如果是前者,可能是highlight JS 的问题,如果是后者,那么是文中我提到的注释后代码也显示为注释的问题吗?如果是,请使用第三版修改的插件,如果不是,请给出具体的问题详情。

  4. 非常好,我一直在寻找,今天终于启用了该插件,这么好的文章,为什么没有人评论?我已经把本文引用到我站了,虽然是新站,但是尽一份努力让更多的人看到!

    • @Mill Wan 感谢这位博主的的认同,其实这篇文章到目前为止已经有至少一千人看到了。我看了你网站引用的文章,不知道关于注释的bug你有没有解决,至于滚动条的问题,我测试的时候在单个HTML网页中也能显示滚动条,而你网站上的代码显示是软换行的样式,猜测可能是你的CSS样式里做了更改。

评论一下呗亲

电子邮件地址不会被公开。 必填项已用*标注