Rails Turbolinks 遇上 多说

VincentJiang · 2015年08月25日 · 最后由 dudu_zzzz 回复于 2016年03月17日 · 3013 次阅读

这两天在为自己的博客http://vrails.com的文章页面中添加评论模块,选用了多说

博客使用了 turbolinks,而多说的评论模块在页面中时有时无,这明显是本人对 turbolinks 理解不够好的原因

以下是多说的代码:

(function() {
  var ds = document.createElement('script');
  ds.type = 'text/javascript';ds.async = true;
  ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
  ds.charset = 'UTF-8';
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ds);
})();

请问我应该如何修改代码,才能让评论模块保持显示?

时有时无是因为 turbolinks 是通过 ajax 方式加载新页面的内容,此过程中 turbolinks 只会请求新的 html 文件,但不会再请求以及加载其他静态文件。所以你的那段代码只有在直接刷新页面的时候才会生效。处理方法也很简单:

// 封装初始化逻辑,并且命名为 `initliazizeDuoshuo`
function initliazizeDuoshuo(){
  var ds = document.createElement('script');
  ds.type = 'text/javascript';ds.async = true;
  ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
  ds.charset = 'UTF-8';
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ds);
}

// document 的 `ready` 事件由浏览器触发,跟往常没有使用 turbolinks 的流程一致,适用网页全新加载的情况
// document 的 `page:load` 事件由 turbolinks 触发,表示新的页面载入完成
// 更多 turbolinks 的事件可以看 https://github.com/rails/turbolinks#events
$(document).on('ready page:load', initliazizeDuoshuo);

另外的方案就是看看 turbolinks 推荐的一个 jQuery 插件,不过我觉得没必要。。。 https://github.com/rails/turbolinks#jqueryturbolinks

最后 Rei 的这篇文章比较不错,推荐之 ~ http://chloerei.com/2013/07/14/turbolinks-guide/

这段代码是在 head 插入 script 引入外部脚本然后立即执行,试试去掉这段代码,在 </body> 前插入

<script src="//static.duoshuo.com/embed.js" async></script>

#1 楼 @martin91 参照你的意见,我的代码改成:

var duoshuoQuery = { short_name: "vrails" };
    function initliazizeDuoshuo() {
      var ds = document.createElement('script');
      ds.type = 'text/javascript';
      ds.async = true;
      ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
      ds.charset = 'UTF-8';
      (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ds);
};
$(document).on('ready page:load', initliazizeDuoshuo);

但还是不成功,在ready的时候会显示,但每次page:load时就不会显示,而只会添加新的:

<script type="text/javascript" async="" src="http://static.duoshuo.com/embed.js" charset="UTF-8"></script>

何解?

#2 楼 @rei 这方法之前试过,不成功,看了你博客的 3 篇关于turbolinks的文章,写得很好,但我还是无法理解到可以解决现时的问题

#3 楼 @jxs471494539 嗯嗯,我看错了,没仔细看你的代码。Rei 的代码应该是能工作的,你那个函数其实最终就是插入一个 <script> 元素而已,用 Rei 的方式就不再需要那个函数了,另外记得要放在 </body> 这个结束标签前面。请确认这两点。

var duoshuoQuery = {short_name:"xxxx"};
$.getScript("http://static.duoshuo.com/embed.js",function(){
  var dus=$(".ds-thread");
  var dr=$("#ds-thread");
  if($(dus).length==1 && $(dr).length==0){
      var el = document.createElement('div');
      el.setAttribute('data-thread-key',$(dus).attr("data-thread-key"));
      el.setAttribute('data-url',$(dus).attr("data-url"));
      DUOSHUO.EmbedThread(el);
      $(dus).html(el);
  }
})

使用 jquery.getScript() 可以完美解决 turbolinks 环境下的问题

需要 登录 后方可回复, 如果你还没有账号请 注册新账号