frank

加入OI Wiki科学委员会
1 简介OI Wiki 致力于成为一个免费开放且持续更新的知识整合站点,大家可以在这里学到关于 OI 竞赛有趣又实...
扫描右侧二维码阅读全文
02
2018/09

加入OI Wiki科学委员会

1 简介

OI Wiki 致力于成为一个免费开放且持续更新的知识整合站点,大家可以在这里学到关于 OI 竞赛有趣又实用的知识,我们为大家准备了 OI 竞赛中的基础知识、常见题型、解题思路以及常用工具等内容,帮助大家更快速深入地学习 OI 竞赛。

OI (Olympiad in Informatics,信息学奥林匹克竞赛)在中国起源于 1984 年,是五大高中学科竞赛之一。自 1989 年起,每年还会选拔出国家集训队选手准备 IOI (International Olympiad in Informatics,国际信息学奥林匹克竞赛)。

2 加入开发

一开始,实在洛谷上有人发帖说OI Wiki,还被置顶了,我便接触了OI Wiki,进入了官网。仔细一瞧,是用mkdocs开发的。浏览了一下网页,我便发现了三个小问题:

  1. 统计出错
  2. 没有回到顶部按钮
  3. 加载缓慢

本着扎实扎实自己的前端思想,便进入了OI Wiki的github仓库

3 修复bug

3.1 改进统计

首先看到的是统计出错的问题,统计中把标题以及页脚的版权声明统统加了进去,导致无文章的页面也有字数。

看了一下base.html的代码,然而内容那一块并没有单独包上一个div,而是涵盖在一个大的div里面,所以我需要用document.getElementsByClassName去获取大块文字,再减去其他模块的文字,写出如下代码:

var cur = document.getElementsByClassName('page-time')[0]
if (cur) {
  var comments = document.getElementById('gitment_container');
  var pos = 0;
  if (comments) {
    pos -= comments.textContent.length;
  }
  comments = document.getElementById('__comments');
  if (comments) {
    pos -= comments.textContent.length;
  }
  var textLength = 0;
  if (pos < 0) textLength = (document.getElementsByClassName('md-content__inner')[0].textContent.slice(0, pos).replace(/\s/g, '').length - document.getElementsByTagName('h1')[0].textContent.replace(/\s/g, '').length - document.getElementsByClassName('page-copyright')[0].textContent.replace(/\s/g, '').length - 4);
  else textLength = (document.getElementsByClassName('md-content__inner')[0].textContent.replace(/\s/g, '').length - document.getElementsByTagName('h1')[0].textContent.replace(/\s/g, '').length - document.getElementsByClassName('page-copyright')[0].textContent.replace(/\s/g, '').length - 4);
  var ti = Math.ceil(textLength / 80);
  cur.innerHTML = `<p>本页面共 ${textLength} 字,预计阅读需要 ${ti} 分钟</p>`;
}

最后一个-4是减去一个title的字数因为没有class只好硬生生的减。以上代码有一个缺陷,当没有字数时,会显示:

本页面共 0 字,预计阅读需要 0 分钟

这样显得不太和谐,于是,我便改进了一下尾部代码:

var cur = document.getElementsByClassName('page-time')[0]
if (cur) {
  var comments = document.getElementById('gitment_container');
  var pos = 0;
  if (comments) {
    pos -= comments.textContent.length;
  }
  comments = document.getElementById('__comments');
  if (comments) {
    pos -= comments.textContent.length;
  }
  var textLength = 0;
  if (pos < 0) textLength = (document.getElementsByClassName('md-content__inner')[0].textContent.slice(0, pos).replace(/\s/g, '').length - document.getElementsByTagName('h1')[0].textContent.replace(/\s/g, '').length - document.getElementsByClassName('page-copyright')[0].textContent.replace(/\s/g, '').length - 4);
  else textLength = (document.getElementsByClassName('md-content__inner')[0].textContent.replace(/\s/g, '').length - document.getElementsByTagName('h1')[0].textContent.replace(/\s/g, '').length - document.getElementsByClassName('page-copyright')[0].textContent.replace(/\s/g, '').length - 4);
  var ti = Math.ceil(textLength / 80);
  if (textLength > 0) cur.innerHTML = `<p>本页面共 ${textLength} 字,预计阅读需要 ${ti} 分钟</p>`;
}

这样的话,当没有字数的时候,就不会显示统计信息。为了鼓励大家为Wiki贡献,所以最终代码如下:

var cur = document.getElementsByClassName('page-time')[0]
if (cur) {
  var comments = document.getElementById('gitment_container');
  var pos = 0;
  if (comments) {
    pos -= comments.textContent.length;
  }
  comments = document.getElementById('__comments');
  if (comments) {
    pos -= comments.textContent.length;
  }
  var textLength = 0;
  if (pos < 0) textLength = (document.getElementsByClassName('md-content__inner')[0].textContent.slice(0, pos).replace(/\s/g, '').length - document.getElementsByTagName('h1')[0].textContent.replace(/\s/g, '').length - document.getElementsByClassName('page-copyright')[0].textContent.replace(/\s/g, '').length - 4);
  else textLength = (document.getElementsByClassName('md-content__inner')[0].textContent.replace(/\s/g, '').length - document.getElementsByTagName('h1')[0].textContent.replace(/\s/g, '').length - document.getElementsByClassName('page-copyright')[0].textContent.replace(/\s/g, '').length - 4);
  var ti = Math.ceil(textLength / 80);
  if (textLength > 0) cur.innerHTML = `<p>本页面共 ${textLength} 字,预计阅读需要 ${ti} 分钟</p>`;
  else cur.innerHTML = `<p>本页面还在建设中,欢迎参与完善!</p>`;
}

总算,这个bug被fix了,详见#257

3.2 添加新功能:返回顶部

这一部分还是很好解决的,我没有使用滚动会顶部,屏幕窗口判断,直接到顶部,贴代码:

javascript:

window.onscroll = function() {scrollFunction()};
 
function scrollFunction() {console.log(121);
    if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
        document.getElementById("myBtn").style.display = "block";
    } else {
        document.getElementById("myBtn").style.display = "none";
    }
}
 
function topFunction() {
    document.body.scrollTop = 0;
    document.documentElement.scrollTop = 0;
}

html:

<button onclick="topFunction()" id="myBtn">
  <svg class="Zi Zi--BackToTop data-tip-left" data-tip="回到顶部" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path d="M16.036 19.59a1 1 0 0 1-.997.995H9.032a.996.996 0 0 1-.997-.996v-7.005H5.03c-1.1 0-1.36-.633-.578-1.416L11.33 4.29a1.003 1.003 0 0 1 1.412 0l6.878 6.88c.782.78.523 1.415-.58 1.415h-3.004v7.005z"></path></svg>
</button>

css:

#myBtn {
    display: none;
    position: fixed; 
    bottom: 3rem; 
    right: 4rem; 
    z-index: 99; 
    border: none;
    outline: none; 
    color: #8590a6;
    cursor: pointer; 
    padding: .7rem; 
    border-radius: .4rem;
}
 
#myBtn:hover {
    background-color: #d3d3d3; 
}

看到知乎上的button,在hover后会出来一个小小的tooltip。我深知tooltip是bootcss里的东西,但是为了轻量化,不想使用前端框架。于是,我便采用了hint.css,但是tooltip中文字并没有居中。最终,我采用了data-tip.css,html改为如下代码:

<button onclick="topFunction()" id="myBtn" class="data-tip-left" data-tip="回到顶部">
  <svg class="Zi Zi--BackToTop data-tip-left" data-tip="回到顶部" fill="currentColor" viewBox="0 0 24 24" width="24" height="24"><path d="M16.036 19.59a1 1 0 0 1-.997.995H9.032a.996.996 0 0 1-.997-.996v-7.005H5.03c-1.1 0-1.36-.633-.578-1.416L11.33 4.29a1.003 1.003 0 0 1 1.412 0l6.878 6.88c.782.78.523 1.415-.58 1.415h-3.004v7.005z"></path></svg>
</button>

这一部分,还是挺容易的,效果也挺好,手机端难看一些,详见#274

3.3 网页加载速度加快

3.3.1 DNS Prefetch

这是一种常用的前端浏览速度加快的方法,使用方式也很简单:

<!-- 启用dns预读取/解析 -->
<meta http-equiv="x-dns-prefetch-control" content="on">
<!-- link里填上你的网址 -->
<link rel="dns-prefetch" href="your-link">

常用的DNS Prefetch在此列出:

<link rel="dns-prefetch" href="//fonts.loli.net">
<link rel="dns-prefetch" href="//cdn.bootcss.com">
<link rel="dns-prefetch" href="//unpkg.com">
<link rel="dns-prefetch" href="//npmcdn.com">
<link rel="dns-prefetch" href="//api.github.com">
<link rel="dns-prefetch" href="//www.google-analytics.com">

虽然增加了DNS查询次数,但是效果也是显而易见

3.3.2 InstantClick

不太了解InstantClick可以去看这篇文章:InstantClick中文文档

贴代码:

<style>.MathJax{outline:0;}</style>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
    showProcessingMessages: false,
    messageStyle: "none",
    extensions: ["tex2jax.js"],
    jax: ["input/TeX", "output/HTML-CSS"],
    tex2jax: {
        inlineMath:  [ ["$", "$"] ],
        displayMath: [ ["$$","$$"] ],
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre','code','a'],
        ignoreClass:"comment-content"
    },
    "HTML-CSS": {
        availableFonts: ["STIX","TeX"],
    }
});
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
</script>
<script src="https://cdn.bootcss.com/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
 <!-- InstantClick -->
<script type="text/javascript" src="https://cdn.bootcss.com/instantclick/3.0.0/instantclick.js" data-no-instant></script>
<script data-no-instant>
InstantClick.on('change', function(isInitialLoad) {
 if (isInitialLoad === false) {
  if (typeof MathJax !== 'undefined') // support MathJax
   MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
  if (typeof ga !== 'undefined') // support google analytics
    ga('send', 'pageview', location.pathname + location.search);
 }
});
InstantClick.init(true);
</script>

上述代码用了MathJax,并对MathJax和Google Analytics做了适配,详见#327

3.3.3 数学公式渲染

这一块暂时还没有找到解决方法,目前用的是MathJax,但是MathJax历史包袱太重了,加载缓慢。考虑KaTeX,但是会发生错位、漏渲染等情况,暂时不打算使用。目前考虑 Wikimedia Mathoid 解决方案(server 那边要求较高),还有 Texoid。希望大家集思广益,给出一个好的解决方案。

4 小结

希望以后这种免费开放的知识站点会越来越多,共建良好的学习氛围!

希望大家多多支持!

Last modification:September 2nd, 2018 at 12:21 am
If you think my article is useful to you, please feel free to appreciate

Leave a Comment