JQuery实现“不蒜子”初始化首次数据
❗❗❗本文最后更新于 248 天前,其中的信息可能已经过时;如有错误请在文章下方评论✅,欢迎纠错🥰!

曲线救国 搞定初值

前期我们讲到使用“不蒜子”实现两行代码统计网站数据

 

关于“不蒜子”

简单来说,“不蒜子”是提供静态页面计数功能的一个第三方服务(欲了解详情可拜访其主页文档),用户只需要在静态的html页面中插入一行脚本一行标签,即可实现计数功能,官方说明如下(带下划线加粗字是重点,要考!

静态网站建站现在有很多快速的技术和平台,但静态是优点也有缺点,由于是静态的,一些动态的内容如评论、计数等等模块就需要借助外来平台,评论有“多说”,计数有“不蒜”!
“不蒜子”与百度统计谷歌分析等有区别:“不蒜子”可直接将访问次数显示在您在网页上(也可不显示);对于已经上线一段时间的网站,“不蒜子”允许您初始化首次数据。
普通用户只需两步走:一行脚本+一行标签,搞定一切。追求极致的用户可以进行意DIY。

实现原理

“不蒜子”的实现原理也很简单,经初步分析,在引入的JS(JavaScript)脚本中,会把当前页面url(或某种唯一标识)注册到其第三方服务器,服务器上保存着url与对应的计数值,点击页面后通过JS更新服务器上的计数值,并在页面初始化时在本地标签加载、显示计数值。

  • 算法a:pv的方式,单个用户连续点击n篇文章,记录n次访问量。
  • 算法b:uv的方式,单个用户连续点击n篇文章,只记录1次访客数。
  • 如果你是用的hexo,打开themes/你的主题/layout/_partial/footer.ejs添加即可。

实例效果参考:

虽然静态页面弱爆了,但JS很强大啊!

需求分析

访问量是一个网站的主要指标(不是必要,如写博客更重要的是思考和学习),网页计数功能也成了我们的一个选择,像百度统计、谷歌统计等后台统计工具非常强大,但要想直接在页面(特别是静态页面)展示数据,“不蒜子”或许是你的不二之选。

但对于那些已经有一定访问量的老站点,访问量需要在原来的数据基础上计算,这就是所谓的“初始化首次数据”

可看到其实“不蒜子”其实有提供“初始化首次数据”的功能,在文档中也有写到:

Q:我的网站已经运行一段时间了,想初始化访问次数怎么办?
A:请先注册登录,自行修改阅读次数。

太好了,于是兴奋地点击主页右上角的“登录”按钮……

 

看看文档下面的评论,应该有网友遇到同样问题,果不出我所料……原来是已经被作者搁置了一年多的功能。

分析问题

不蒜子之所以被称为「geek 的计数器」,就是因为它的安装使用非常简单——只需要加载计数器 js 脚本,以及使用 span 标签显示计数器结果就可以了。其余所有的事情,都交给用户的 css 去控制。因此,自然,这个「所有的事情」也包括了最终显示的值是多少。因此,我们可以在最终显示的数字上做一些手脚。

思路如下:不直接显示计数值,每次显示之前先把拿到的计数值加上一个初始值,再进行显示,而这个中间处理可通过JS/JQuery来完成。

曲线救国——利用JS/JQuery纠正计数值

按“不蒜子”官方教程提示,在需要显示计数的位置插入对应的两行html代码,即可实现显示网站访问量(注意uv是一个IP记一次,而pv是每刷新一次记一次)。

一般解法

不蒜子的站点 PV 对应的标签是这样的

<span id="busuanzi_value_site_pv"></span>

既然如此,我们只需要在页面上用 js 取得这个标签中的值,而后加上一个偏移量作为初始值就可以了。如果使用 jQuery,可以这样做

<script src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
    $(document).ready(
        var busuanziSiteOffset = parseInt(100000);
        function fixCount() {
            if ($("#busuanzi_container_site_pv").css("display") != "none") {
                $("#busuanzi_value_site_pv").html(parseInt($("#busuanzi_value_site_pv").html()) + busuanziSiteOffset);
            }
        }
    );
</script>

余下唯一的问题,就是不蒜子的 js 代码,是通过异步的方式加载的。而在其加载完成之前,上述 span 标签会整个被隐藏起来,不可见。于是,这样的朴素的修复就会失效了。

对付「异步」,一个朴素的处理方式是定期轮询。比如这样

<script src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
    $(document).ready(function() {
        var int = setInterval(fixCount, 100);
        var busuanziSiteOffset = parseInt(10000);
        function fixCount() {
            if ($("#busuanzi_container_site_pv").css("display") != "none") {
                clearInterval(int);
                $("#busuanzi_value_site_pv").html(parseInt($("#busuanzi_value_site_pv").html()) + busuanziSiteOffset);
            }
        }
    });
</script>

Hexo 的解法

在上面的分析中,我们实际上已经有了完整的解法。不过,这样的解法可定制性非常差。试想,在需要修改初始值的时候,都需要深入到代码中去,而后修改 var busuanziSiteOffset = parseInt(10000); 的值。这种事情,想想就令人崩溃。

对于 Hexo 来说,在站点或主题配置中的变量,可以在主题模版中引用得到。于是,我们可以这样做。

#config.yml
busuanzi: true
busuanzi_site_offset: 100000

以及这样做。

#hexo_footer.swig
{% if theme.busuanzi %}
<!-- 不蒜子 -->
<script async src="//cdn.busuanzi.ibruce.info/cdn/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<!-- 不蒜子计数初始值纠正 -->
<script src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
    $(document).ready(function() {
        var int = setInterval(fixCount, 100);
        var busuanziSiteOffset = parseInt({{ theme.busuanzi_site_offset }});
        function fixCount() {
            if ($("#busuanzi_container_site_pv").css("display") != "none") {
                clearInterval(int);
                $("#busuanzi_value_site_pv").html(parseInt($("#busuanzi_value_site_pv").html()) + busuanziSiteOffset);
            }
        }
    });
</script>
{% endif %}

代码解释

$(document).ready方法在文档加载后执行,即让网页加载完毕后执行我们的JS代码,再用setInterval设置50毫秒周期性调用fixCount()方法。countOffset这个变量就是我们要加上的初始值了(可通过网站之前的统计工具如百度统计谷歌统计查看到),这里设为20000。在重头戏fixCount()方法内,先判断标签的display属性,当不为”none”时(异步加载数据完成)获得原始数值,加上自定义的额初始值后再写入标签,最后关掉Interval,大功告成!

这样,当我们访问页面时,会不停的检测标签的状态,一旦计数值加载出来就加上初始值纠正,再显示,解决了“不蒜子”不能初始化首次数据的问题。

我的不蒜子代码(可一键复制)

切记修改初始数值!!!
<!-- 引入不蒜子计数 -->
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js">
</script>

<!-- 不蒜子计数初始值纠正 -->
<script>
    $(document).ready(function() {
        var delay = setInterval(fixCount, 50);  // 50ms周期检测函数
        var countOffsetpv = 10945;  // 初始化首次pv数据
        var countOffsetuv = 203;  // 初始化首次uv数据
        function fixCount() {                   
            if ($("#busuanzi_container_site_pv").css("display") != "none")
            {
              $("#busuanzi_value_site_pv").html(parseInt($("#busuanzi_value_site_pv").html()) + countOffsetpv); // 加上初始数据 
              clearInterval(delay); // 停止检测
            }  
            if ($("#busuanzi_container_site_uv").css("display") != "none")
            {
              $("#busuanzi_value_site_uv").html(parseInt($("#busuanzi_value_site_uv").html()) + countOffsetuv); // 加上初始数据 
              clearInterval(delay); // 停止检测
            }
        }           
    });
</script>

<!-- 不蒜子主体显示部分 -->
<span id="busuanzi_container_site_pv" style='display:none'>
    📬本站已被点击
    <span id="busuanzi_value_site_pv" style="color:#ffff00">
        <i class="fa fa-spinner fa-spin"></i>
    </span>次
</span>
<br>
<span id="busuanzi_container_site_uv" style='display:none'>
    ⌛已为
    <span id="busuanzi_value_site_uv" style="color:#ffff00">
        <i class="fa fa-spinner fa-spin"></i>
    </span>位踩坑者提供港湾
</span>

效果如下

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇