不蒜子计数器初始化的 Native JS 方法
不蒜子 是开始于 2015 年的静态页面计数服务,可以将页面的访问次数显示在页面之上。但是不蒜子计数系统使用页面 URL 作为 identifier,所以会遇到两种情况导致计数会出现偏差:
- 页面的 URL 变化了导致数字归零
- 你在页面调试的时候不小心多刷新了好几下
- 大家都在使用 localhost 进行调试
基于以上可能会导致不蒜子计数偏低或者偏高的情况,不蒜子本来计划推出账号系统供站长重置、或者调整站点统计数据,但是这个计划是 2016 年就提出来了的,所以看来等待通过不蒜子官方渠道修改数值是没有希望了,所以还是得自己解决吧。
当然你可能在好几篇文章里读到过类似的解决方案,比如 这篇写于 2017 年的 SEO 做的比较好的 和 这篇更早一些的。但是这两个方案都需要 jQuery,正像我在 这篇文章 中提到的一样,我并不喜欢 jQuery。所以才会有这篇文章。
不蒜子会在 Fetch 到数据之前隐藏 container——不蒜子的 JS 给 #busuanzi_container_site_uv
元素设置了 display: none
,然后当 Fetch 到数据的时候,就会给设置了 display: inline
。所以我们可以判断这个元素的 display 属性,一旦变为 inline 就可以修改数据了。
Talk is cheap, let me show you code.
if (document.getElementById('busuanzi_container_site_uv').ownerDocument.defaultView.getComputedStyle(document.getElementById('busuanzi_container_site_uv'), null).display === 'inline') {
document.getElementById('busuanzi_value_site_uv') = parseInt(document.getElementById('busuanzi_value_site_uv').innerHTML) + parseInt('100000000000');
}
但是上面那些使用 jQuery 的教程会告诉你,不蒜子的 JS 是异步加载的。所以最简单的 workaround 就是我们可以去掉加载不蒜子 JS 的 async
,但是不蒜子既然设计了异步、甚至帮你在加载数据之前隐藏了 container。所以,我们还是继续保留不蒜子 JS 的 async 加载吧。
由于不蒜子没有给我们一个 callback,所以我们依然需要借助 #busuanzi_container_site_uv
的 display 属性变化。这次我们使用轮询的方法。
var int = setInterval(fixCount, 50);
function fixCount() {
if (document.getElementById('busuanzi_container_site_uv').ownerDocument.defaultView.getComputedStyle(document.getElementById('busuanzi_container_site_uv'), null).display === 'inline') {
clearInterval(int);
document.getElementById('busuanzi_value_site_uv') = parseInt(document.getElementById('busuanzi_value_site_uv').innerHTML) + parseInt('100000000000');
}
}
当然,这些都有了,剩下的事情就很简单了,比如把 100000000000
替换成 front-matter 中或者主题配置文件中可以配置的变量,比如使用 theme.busuanzi.offset
或者 config.busuanzi_offset
;当然你还可以复用一些元素选择器让代码变短一些。
然后就是看个效果吧:不蒜子初始化测试,这是「Suka」主题的 Demo 页面之一。如果你想自己实现不蒜子 offset,你可以参考一下「Suka」主题这条 PR。