我有一个fb-like-box
和一个twitter-timeline
,官方的facebook页面和twitter小部件。但是,在实际导航(侧边栏中的链接执行ajax加载)时,例如点击徽标时,这两个小部件就会消失得无影无踪。
在刷新页面时,窗口小部件再次按预期显示。
<div id="social_bar">
<div id="facebook_like_box">
<div class="fb-like-box" data-href="https://www.facebook.com/Gx.Edg" data-width="234" data-height="500" data-colorscheme="light" data-show-faces="true" data-header="true" data-stream="false" data-show-border="true"></div>
</div>
<a class="twitter-timeline" href="https://twitter.com/gxEDGE" data-widget-id="308092518074040321"></a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</div>
根本原因是Turbolinks如何与标题脚本交互。 @peteykun在他的回答中提供了正确的解决方案,虽然它已经过时并且缺乏详尽的解释。在撰写本文时,Rails 5使用Turbolinks 5。
当您第一次访问Rails站点上的页面(或刷新页面)时,页面将正常获取而不受Turbolinks的干扰。预期的浏览器事件触发,JavaScript执行,所有内容都正确呈现。当您从该页面导航到同一域上的另一个页面(即单击链接)时,会出现问题。当发生这种情况时,Turbolinks intercepts the new page request会发出更快的请求。对细节进行着色,最终结果是预期的浏览器事件不会像通常那样触发。没有事件,没有JavaScript。没有JavaScript,没有渲染。根据Turbolinks GitHub:
您可能习惯于安装JavaScript行为以响应window.onload,DOMContentLoaded或jQuery ready事件。使用Turbolinks,这些事件只会响应初始页面加载而不会在任何后续页面更改后触发。
最好和最简单的解决方案是收听Turbolink的事件而不是标准的浏览器事件。
幸运的是,有一个由website撰写的user @reed of GitHub,它致力于重写各种常用的JavaScripts以与Turbolinks兼容。不幸的是,该网站上目前的解决方案是针对Turbolinks的早期版本编写的,并且不会开箱即用。假设他们尚未更新网站,您需要进行一些更改。
首先,将page:*
形式的所有事件绑定更改为turbolinks:*
。 Turbolinks中的event namespaces were changed 5.这是让@ed的Twitter coffeescript(解决方案#2)工作所需的唯一变化。至于Facebook coffeescript,没有像turbolinks:fetch
或turbolinks:change
这样的事情,但这没关系。继续阅读以获得更优雅的解决方案。
里德的Facebook coffeescript使用Javascript将#fb-root
元素从旧页面的主体转移到新页面。据我了解,这样做是为了保留Facebook的功能。 Turbolinks 5有一个新功能,允许您将页面元素标记为permanent。用户@pomartel提到了这个here,我相信这是一个更优雅的解决方案。只需将data-turbolinks-permanent
属性添加到#fb-root
div,我们就不再需要saveFacebookRoot
和restoreFacebookRoot
函数。
完整的Facebook解决方案如下。在<body>
:
<body>
<div id="fb-root" data-turbolinks-permanent></div>
在<head>
:
<%= javascript_include_tag 'facebook_sdk', 'data-turbolinks-track': 'reload' %>
和facebook_sdk.coffee
文件,属于./app/assets/javascripts
:
$ ->
loadFacebookSDK()
bindFacebookEvents() unless window.fbEventsBound
bindFacebookEvents = ->
$(document)
.on('turbolinks:load', ->
FB?.XFBML.parse()
)
@fbEventsBound = true
loadFacebookSDK = ->
window.fbAsyncInit = initializeFacebookSDK
$.getScript("//connect.facebook.net/en_US/sdk.js")
initializeFacebookSDK = ->
FB.init
appId : 'YOUR-APP-ID-HERE'
status : true
cookie : true
xfbml : true
autoLogAppEvents : true
version: 'v2.11'
不要忘记将Facebook和Twitter咖啡添加到precompiled asset pipeline!