Turbolinks 5.0 和 Facebook SDK
Turbolinks 5.0 and Facebook SDK
上周我升级到 Rails 5,它使用的是 Turbolinks 5.0。我使用以下脚本通过 Turbolinks 3.0 加载 Facebook 点赞按钮:
fb_root = null
fb_events_bound = false
$ ->
loadFacebookSDK()
bindFacebookEvents() unless fb_events_bound
bindFacebookEvents = ->
$(document)
.on('page:fetch', saveFacebookRoot)
.on('page:change', restoreFacebookRoot)
.on('page:load', ->
FB?.XFBML.parse()
)
fb_events_bound = true
saveFacebookRoot = ->
fb_root = $('#fb-root').detach()
restoreFacebookRoot = ->
if $('#fb-root').length > 0
$('#fb-root').replaceWith fb_root
else
$('body').append fb_root
loadFacebookSDK = ->
window.fbAsyncInit = initializeFacebookSDK
$.getScript("//connect.facebook.net/nl_NL/all.js#xfbml=1")
initializeFacebookSDK = ->
FB.init
appId : 'YOUR_APP_ID'
channelUrl: '//WWW.YOUR_DOMAIN.COM/channel.html'
status : true
cookie : true
xfbml : true
在 Turbolinks 5.0 中,赞按钮只会在页面重新加载时显示。当我不重新加载页面而只是单击 link 时,我收到此错误:
Blocked a frame with origin "https://www.facebook.com" from accessing a frame with origin "http://localhost:3000". The frame requesting access has a protocol of "https", the frame being accessed has a protocol of "http". Protocols must match.
有人知道如何解决这个问题吗?
这是因为某些事件在 Turbolinks 5
中被重命名并且与 Turbolinks 3
不兼容。我的建议是尝试在 javascripts/
文件夹下创建一个名为 compatibility.coffee
的文件
compatibility.coffee
{defer, dispatch} = Turbolinks
handleEvent = (eventName, handler) ->
document.addEventListener(eventName, handler, false)
translateEvent = ({from, to}) ->
handler = (event) ->
event = dispatch(to, target: event.target, cancelable: event.cancelable, data: event.data)
event.preventDefault() if event.defaultPrevented
handleEvent(from, handler)
translateEvent from: "turbolinks:click", to: "page:before-change"
translateEvent from: "turbolinks:request-start", to: "page:fetch"
translateEvent from: "turbolinks:request-end", to: "page:receive"
translateEvent from: "turbolinks:before-cache", to: "page:before-unload"
translateEvent from: "turbolinks:render", to: "page:update"
translateEvent from: "turbolinks:load", to: "page:change"
translateEvent from: "turbolinks:load", to: "page:update"
loaded = false
handleEvent "DOMContentLoaded", ->
defer ->
loaded = true
handleEvent "turbolinks:load", ->
if loaded
dispatch("page:load")
jQuery?(document).on "ajaxSuccess", (event, xhr, settings) ->
if jQuery.trim(xhr.responseText).length > 0
dispatch("page:update")
如果您更喜欢使用原生 Turbolinks 5 事件,您可以将此脚本添加到您的 Rails 资产中:
// FacebookSDK
// https://developers.facebook.com/docs/plugins/page-plugin/
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s);
js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk')); // Replace 'facebook-jssdk' with your page id.
// Compatibility with Turbolinks 5
(function($) {
var fbRoot;
function saveFacebookRoot() {
if ($('#fb-root').length) {
fbRoot = $('#fb-root').detach();
}
};
function restoreFacebookRoot() {
if (fbRoot != null) {
if ($('#fb-root').length) {
$('#fb-root').replaceWith(fbRoot);
} else {
$('body').append(fbRoot);
}
}
if (typeof FB !== "undefined" && FB !== null) { // Instance of FacebookSDK
FB.XFBML.parse();
}
};
document.addEventListener('turbolinks:request-start', saveFacebookRoot)
document.addEventListener('turbolinks:load', restoreFacebookRoot)
}(jQuery));
发件人:https://gist.github.com/6temes/52648dc6b3adbbf05da3942794b97a00
这是将 Turbolinks 5 与 Facebook SDK 集成的方法。
在您的布局模板中:
// /source/layouts/layout.erb
<body class="<%= page_classes %>">
<%= yield %>
<div id='permanent' data-turbolinks-permanent></div>
</body>
然后在您的 javascript 中使用 jQuery 此处:
function FBInit() {
FB.init({
appId : 'YOUR_KEY',
xfbml : true,
version : 'v2.8'
});
$('#permanent').append( $('#fb-root').detach() );
};
$(document).ready(function(){
$.getScript( "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8", FBInit);
});
$(document).on('turbolinks:load', function(event){
if (typeof FB !== "undefined" && FB !== null) {
FB.XFBML.parse();
}
});
$(document).on("turbolinks:before-cache", function() {
$('[data-turbolinks-no-cache]').remove();
});
然后像这样使用任何使用 data-turbolinks-no-cache 属性的 Facebook 插件:
<div data-turbolinks-no-cache
class="fb-like"
data-href="#"
data-layout="standard"
data-action="like"
data-size="small"
data-show-faces="true"
data-share="true"></div>
上周我升级到 Rails 5,它使用的是 Turbolinks 5.0。我使用以下脚本通过 Turbolinks 3.0 加载 Facebook 点赞按钮:
fb_root = null
fb_events_bound = false
$ ->
loadFacebookSDK()
bindFacebookEvents() unless fb_events_bound
bindFacebookEvents = ->
$(document)
.on('page:fetch', saveFacebookRoot)
.on('page:change', restoreFacebookRoot)
.on('page:load', ->
FB?.XFBML.parse()
)
fb_events_bound = true
saveFacebookRoot = ->
fb_root = $('#fb-root').detach()
restoreFacebookRoot = ->
if $('#fb-root').length > 0
$('#fb-root').replaceWith fb_root
else
$('body').append fb_root
loadFacebookSDK = ->
window.fbAsyncInit = initializeFacebookSDK
$.getScript("//connect.facebook.net/nl_NL/all.js#xfbml=1")
initializeFacebookSDK = ->
FB.init
appId : 'YOUR_APP_ID'
channelUrl: '//WWW.YOUR_DOMAIN.COM/channel.html'
status : true
cookie : true
xfbml : true
在 Turbolinks 5.0 中,赞按钮只会在页面重新加载时显示。当我不重新加载页面而只是单击 link 时,我收到此错误:
Blocked a frame with origin "https://www.facebook.com" from accessing a frame with origin "http://localhost:3000". The frame requesting access has a protocol of "https", the frame being accessed has a protocol of "http". Protocols must match.
有人知道如何解决这个问题吗?
这是因为某些事件在 Turbolinks 5
中被重命名并且与 Turbolinks 3
不兼容。我的建议是尝试在 javascripts/
文件夹下创建一个名为 compatibility.coffee
compatibility.coffee
{defer, dispatch} = Turbolinks
handleEvent = (eventName, handler) ->
document.addEventListener(eventName, handler, false)
translateEvent = ({from, to}) ->
handler = (event) ->
event = dispatch(to, target: event.target, cancelable: event.cancelable, data: event.data)
event.preventDefault() if event.defaultPrevented
handleEvent(from, handler)
translateEvent from: "turbolinks:click", to: "page:before-change"
translateEvent from: "turbolinks:request-start", to: "page:fetch"
translateEvent from: "turbolinks:request-end", to: "page:receive"
translateEvent from: "turbolinks:before-cache", to: "page:before-unload"
translateEvent from: "turbolinks:render", to: "page:update"
translateEvent from: "turbolinks:load", to: "page:change"
translateEvent from: "turbolinks:load", to: "page:update"
loaded = false
handleEvent "DOMContentLoaded", ->
defer ->
loaded = true
handleEvent "turbolinks:load", ->
if loaded
dispatch("page:load")
jQuery?(document).on "ajaxSuccess", (event, xhr, settings) ->
if jQuery.trim(xhr.responseText).length > 0
dispatch("page:update")
如果您更喜欢使用原生 Turbolinks 5 事件,您可以将此脚本添加到您的 Rails 资产中:
// FacebookSDK
// https://developers.facebook.com/docs/plugins/page-plugin/
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s);
js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk')); // Replace 'facebook-jssdk' with your page id.
// Compatibility with Turbolinks 5
(function($) {
var fbRoot;
function saveFacebookRoot() {
if ($('#fb-root').length) {
fbRoot = $('#fb-root').detach();
}
};
function restoreFacebookRoot() {
if (fbRoot != null) {
if ($('#fb-root').length) {
$('#fb-root').replaceWith(fbRoot);
} else {
$('body').append(fbRoot);
}
}
if (typeof FB !== "undefined" && FB !== null) { // Instance of FacebookSDK
FB.XFBML.parse();
}
};
document.addEventListener('turbolinks:request-start', saveFacebookRoot)
document.addEventListener('turbolinks:load', restoreFacebookRoot)
}(jQuery));
发件人:https://gist.github.com/6temes/52648dc6b3adbbf05da3942794b97a00
这是将 Turbolinks 5 与 Facebook SDK 集成的方法。
在您的布局模板中:
// /source/layouts/layout.erb
<body class="<%= page_classes %>">
<%= yield %>
<div id='permanent' data-turbolinks-permanent></div>
</body>
然后在您的 javascript 中使用 jQuery 此处:
function FBInit() {
FB.init({
appId : 'YOUR_KEY',
xfbml : true,
version : 'v2.8'
});
$('#permanent').append( $('#fb-root').detach() );
};
$(document).ready(function(){
$.getScript( "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8", FBInit);
});
$(document).on('turbolinks:load', function(event){
if (typeof FB !== "undefined" && FB !== null) {
FB.XFBML.parse();
}
});
$(document).on("turbolinks:before-cache", function() {
$('[data-turbolinks-no-cache]').remove();
});
然后像这样使用任何使用 data-turbolinks-no-cache 属性的 Facebook 插件:
<div data-turbolinks-no-cache
class="fb-like"
data-href="#"
data-layout="standard"
data-action="like"
data-size="small"
data-show-faces="true"
data-share="true"></div>