Artitalk是一款通过leancloud实现的可实时发布说说的js。点击我博客顶部的“说说”,看到的即为artitalk界面。

本文主要记录artitalk 2.4.x在pjax网站的使用方法及美化过程。

在pjax网站使用artitalk

因为artitalk并没有提供重载函数,因此目前的解决办法主要有两种:

  1. 在该页面通过各种手段进行一次刷新,例如:

    • 官方文档中的方法,自动在artitalk界面刷新

      1
      2
      3
      4
      5
      6
      $(document).ready(function () {
      if(location.href.indexOf("#reloaded")==-1){
      location.href=location.href+"#reloaded";
      location.reload();
      }
      })
    • 对于volantis主题,将artitalk页面的window.location.pathname加入到主题配置的pjax黑名单

  2. 手动清除artitalk初始化的AV对象并重新加载js文件

此处我们讨论的是第二种方法。参照该pr的思路,我们需要在页面重载的时候删除掉原本的window.AV对象,接着重新加载artitalk.js。

数据迁移

因为valine同样依赖window.AV提供服务。使用上述方法解决artitalk问题的代价是:在加载artitalk界面过程中,artitalk将valine的window.AV替换成了自己的。所以首先我们需要确保artitalk和valine使用的是相同的LeanCloud应用。

按照artitalk官方文档的说法:

因为 LeanCloud 功能的限制。若想同时使用 valine 和 artitalk,请在 class 中添加名为 Comment 的 class。不推荐在存储 valine 的应用中新建名为 shuoshuo 的 class,可能会出现神奇的 bug。

所以我们需要将valine的数据迁移到artitalk中(如果本来用的就是相同的应用可以跳过该步骤):

  1. 在artitalk使用的LeanCloud应用中新建Comment class,如果有使用访问量功能的话还需要新建Counter class

  2. 将原来valine应用中的CommentCounter class导出(吐槽一句:为什么只能在中午十二点前导出啊!维护用得着整整半天吗?!

    image-20200827151353004

  3. 将导出的CommentCounter class导入到artitalk使用的应用中

    image-20200827151808051

  4. 将配置文件中valine使用的ID和Key改成和artitalk相同的。

具体的实现过程

这一步是我自己摸索出来的,可能有些繁琐。

参考该文章里重载整个js文件的实现思路,我们可以将artitalk引入到网站并加上data-pjax属性,并在每次pjax切换页面时对带有data-pjax属性的js文件进行重载。

但问题是,我们并不应该让artitalk在每个页面都执行,只有位于artitalk页面时才有执行的必要,因此我们需要手动修改artitalk源码并重新构建,具体流程是:

克隆Artitalk仓库并切换到指定commit

查看版本历史后发现1df35c9似乎是最后通过测试的commit,因此我们使用该次commit。

1
2
3
git clone https://github.com/ArtitalkJS/Artitalk
cd Artitalk
git checkout 1df35c9

加入对当前所处页面的判断

我们需要加入对当前页面的判断,只有当前页是artitalk页时才需要执行脚本。以我的博客为例,artitalk页面的window.location.pathname/personal-space/,我做的操作是:

  • src/main.js套一个判断

    1
    2
    3
    if (window.location.pathname==='/personal-space/'){
    // 文件原本内容
    }
  • av.min.js套一个判断

    1
    2
    3
    4
    5
    6
    if (window.location.pathname==='/personal-space/'){
    if (window.AV!==undefined){
    delete window.AV
    }
    // 文件原本内容
    }

安装依赖并构建

1
2
3
4
5
6
# for yarn
yarn
yarn gulp
# for npm
npm install
npm run gulp

在网站中引入构建好的文件

dist/artitalk.min.js放入博客的source/js目录。将这行加到footer里:

1
<script data-pjax src='/js/artitalk.min.js'></script>

修改pjax:complete函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 这是Valine的重载函数
VA: function () {
if (!valine) {
var valine = new Valine()
valine.init({
el: '#vcomments',
appId: mashiro_option.v_appId,
appKey: mashiro_option.v_appKey,
path: window.location.pathname,
placeholder: '你是我一生只会遇见一次的惊喜 ...',
visitor: true
})
}
}
// pjax:complete内
pjax(...,...,{...}).on('pjax:complete',function (){
// 重载artitalk
$("script[data-pjax], .pjax-reload script").each(function () {
$(this).parent().append($(this).remove());
});
// 再重载valine
VA()
})

这一步要注意顺序,实测如果先重载valine再重载artitalk,会出现valine能正确显示评论条数却不能显示内容的bug。

加入artitalk页面

万事具备,最后只需要在artitalk对应的md文件内写入:

1
2
3
4
5
6
7
8
9
10
---
title: 标题
comments: false
---
<div id="artitalk_main"></div>
<script>
var appID="你的ID";
var appKEY="你的Key";
// 各种配置项请参考artitalk官方文档
</script>

artitalk美化(自定义样式)

简单需求

如果只是想换个背景色,我们可以通过简单指定配置项的color1/color2/color3来生效。例如我的博客,使用的配置是:

1
2
3
var color1='#d9d9f3';
var color2='#ceefe4';
var color3='black';

复杂需求

对于更复杂的美化需求,这篇文章给出了多个自定义样式。然而,但实际使用中会发现文中的自定义方法不能生效。

我们来看一下artitalk添加的默认样式:

1
2
3
#artitalk_main .cbp_tmtimeline>li:nth-child(odd) .cbp_tmlabel {
......
}

再来看看自定义的样式:

1
2
3
.cbp_tmtimeline>li:nth-child(odd) .cbp_tmlabel {
......
}

根据css优先级的规则:

内联 > ID选择器 > 类选择器 > 标签选择器。

在其他部分相同的情况下,artitalk的默认样式多使用了一个ID选择器,在优先级上是高于我们的自定义样式的,因此我们的自定义样式无法成功应用。

解决方法有三种:

  1. 为自定义样式同样加上ID选择器,并保证自定义样式位于默认样式后。

    当优先级与多个 CSS 声明中任意一个声明的优先级相等的时候,CSS 中最后的那个声明将会被应用到元素上。

  2. 为自定义样式中的每个属性加上!important

    当在一个样式声明中使用一个 !important 规则时,此声明将覆盖任何其他声明。

  3. 指定cssurl

    根据artitalk配置项文档,当我们指定cssurl项时,默认样式将不会被加载,转而使用位于cssurl的css文件。

    我们可以将仓库中的main.css拷贝出来,把指定的条目换成我们的自定义样式,并将修改后的css文件上传到某个网站,最后把上传后得到的直链地址填到cssurl项即可。