J'utilise Facebook comme système d'adhésion de mon site Web. Il utilise le code pour générer un contrôle de connexion, permettant aux utilisateurs de se connecter via leur compte Facebook. C'est essentiellement un clic s'ils sont déjà membres, 2 s'ils ne le sont pas (pour accorder des autorisations).
J'ai un problème cependant ... les commentaires suggèrent que le bouton de connexion ne se charge pas toujours correctement. Au lieu de charger le contrôle de connexion facebook, il indique simplement (dans le texte) "connexion via facebook" - ce que dirait le bouton de connexion si le contrôle était chargé avec succès.
Les tests montrent que c'est ce qui se produit lorsque le SDK de javascript de Facebook ne parvient pas à se charger complètement (pour une raison quelconque). J'ai vu des cas où un # dans l'URL empêche le SDK de se charger.
Pour mieux prendre en charge ce problème, comment pourrais-je détecter si le SDK de javascript de Facebook est chargé et s'il est prêt? De cette façon, si cela échoue, je peux laisser une sorte de note à l'utilisateur.
Voici comment il est actuellement ajouté à la page:
<script>
window.fbAsyncInit = function () {
FB.init({
appId: '***************',
status: true,
cookie: true,
xfbml: true
});
FB.Event.subscribe('auth.login', function (response) {
window.location.reload();
});
};
(function () {
var e = document.createElement('script'); e.async = true;
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
document.getElementById('fb-root').appendChild(e);
} ());
</script>
Vous devez charger la bibliothèque Javascript de manière asynchrone et placer toutes vos fonctions liées au bloc fonction dans la méthode window.fbAsyncInit
:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Additional initialization code here
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
Ce code charge le SDK de manière asynchrone afin qu'il ne bloque pas le chargement d'autres éléments de votre page. Ceci est particulièrement important pour assurer chargement rapide de pages pour les utilisateurs et les robots de référencement.
Les URL dans le code ci-dessus sont relatives au protocole. Cela laisse le navigateur pour charger le SDK sur le même protocole (HTTP ou HTTPS) que le fichier contenant la page, ce qui empêchera les avertissements de "contenu non sécurisé".
La fonction assignée à
window.fbAsyncInit
est exécutée dès que le SDK est chargé. Tout code que vous souhaitez exécuter après le chargement du SDK devrait être placé dans cette fonction et après l'appel àFB.init
. Par exemple, c’est là que vous testez l’état de connexion du fichier utilisateur ou vous abonner à n’importe quel événement Facebook dans lequel votre application est intéressé.
Un exemple rapide est le suivant:
<div id="fb-root"></div>
<script>
var isLoaded = false;
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
isLoaded = true;
// Additional initialization code here
};
function checkIfLoaded() {
if(isLoaded) console.log("LOADED!");
else console.log("NOT YET!");
return false;
}
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
<a href="#" onclick="checkIfLoaded();">Check</a>
(Il suffit de cliquer deux fois sur le lien check
} _)
Veuillez noter que vous pouvez toujours construire le lien de connexion côté serveur et _ sans JavaScript. Exemple utilisant le PHP-SDK :
$loginUrl = $facebook->getLoginUrl();
...
...
<a href="<?php echo $loginUrl; ?>">
<img src="http://static.ak.fbcdn.net/rsrc.php/zB6N8/hash/4li2k73z.gif">
</a>
Déclencher un événement lorsque le SDK est chargé:
window.fbAsyncInit = function() {
FB.init({appId: "#{KeyManager.facebook_app_id}", status: true, cookie: true, xfbml: true});
jQuery('#fb-root').trigger('facebook:init');
};
Et écoutez l'événement comme ceci:
$("#fb-root").bind("facebook:init", function() {
..
});
Il suffit de rechercher un objet FB après le chargement du FB JS SDK sync/async comme indiqué:
if (typeof FB !== 'undefined') {
alert("FB JS API is available now");
} else {alert("do something...")}
C'est une vérification suffisante pour appeler n'importe quelle méthode liée à l'API JS de Facebook en toute sécurité.
Selon cette page http://www.techsirius.com/2014/04/detect-social-SDK-didnt-load.html
$(window).load(function(){
if(typeof window.FB == 'undefined'){
alert('Facebook SDK is unable to load, display some alternative content for visitor');
}
else{
alert('Facebook is working just fine');
}
});
Quels globaux ce fichier JS introduit-il?
Disons que cela crée un
var FaceBook = function() {//make friends! Or whatever...}
Vous pouvez tester if (FaceBook)
et partir de là.
Il semble probable qu'ils vous donnent une sorte d'événement de chargement lorsque leur infrastructure est démarrée, pour ainsi dire.
Si vous utilisez jQuery (et que vous avez chargé jQuery avant l'initialisation du FB), vous pouvez utiliser une opération différée pour exécuter une initialisation supplémentaire.
<script>
window.fbLoaded = $.Deferred();
window.fbAsyncInit = function() {
FB.init({
appId : '----------',
xfbml : true,
status : true,
version : 'v2.7'
});
window.fbLoaded.resolve();
};
(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";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
Ensuite, ailleurs (dans un fichier JS), vous pouvez le faire (en fait, la clé de cette méthode est de pouvoir le placer à autant d’endroits que vous le souhaitez et ils seront tous déclenchés):
window.fbLoaded.done(function () { alert('FB initialized'); });
Remarque: Si l'initialisation est terminée AVANT que vous ajoutiez l'événement done
, il se déclenchera immédiatement (c'est ainsi que fonctionne la procédure différée). Vous pouvez donc le placer où vous voulez.
Assurez-vous de tester le comportement souhaité si l’API n’est jamais initialisée (il suffit de commenter le (function(d,s,id)... part
// Load Facebook JS SDK
(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 = 'https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.11';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
// Create a new promise, set to resolve using the global function `fbAsyncInit`,
// which the Facebook JS SDK will call once it's ready.
(new Promise((resolve, reject) => {
window.fbAsyncInit = resolve;
}).then(() => {
// ... your code here ...
});
Je l'utilise depuis quelques jours:
var isLoaded = false;
$(document).on('DOMSubtreeModified', function () {
if ($('#fb-root').length && !isLoaded) {
isLoaded = true;
// ...
}
});
Qu'est-ce que tu penses ?
Comme indiqué dans d'autres réponses; avec merci à @ifaour & @Leo Romanovsky; Le meilleur moyen de détecter si le SDK est chargé est de déclencher un événement lorsque fbAsyncInit est appelé.
Si l'événement est capturé, le SDK est chargé. Le code ci-dessous montre comment cela pourrait être réalisé:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
// Fire an event when the FB library asynchronously is loaded
$("#fb-root").trigger("facebook:init");
// Additional initialization code here
};
// Load the SDK Asynchronously
(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";
fjs.parentNode.insertBefore(js, fjs);
}
(document, "script", "facebook-jssdk"));
</script>
// Somewhere else in the code
$(document).ready(function () {
$("#fb-root").bind("facebook:init", function () {
console.log("The event is fired FB SDK object is ready to be used.");
});
});
Si l'événement n'est pas déclenché, vous pouvez ajouter une minuterie pour vérifier si l'objet FB est «non défini» et afficher le message approprié.
Note 1: Inconvénient: il pourrait y avoir un léger retard jusqu'à ce que cet événement soit déclenché.
Note 2: "les commentaires suggèrent que le bouton de connexion ne se charge pas toujours correctement". Je sais que la navigation privée FFv49 bloque l'appel à fb.
var FB;
jQuery.fbInit = function(app_id) {
window.fbAsyncInit = function() {
FB.init({
appId : app_id,
status : true,
channelUrl: '#',
cookie : true,
xfbml : true
});
FB = FB;
getLoginStatus();
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/it_IT/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
$('<div />').attr('id','fb-root').appendTo('body');
};
/**
* https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
*/
function getLoginStatus() {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
$('#fb-root').trigger('facebook:init',[response]);
} else if (response.status === 'not_authorized') {
$('#fb-root').trigger('facebook:init',[response]);
} else {
$('#fb-root').trigger('facebook:init',[response]);
}
});
}
Si vous voulez vérifier le statut d'un autre javascript (avec la suggestion de @Leo Romanovsky)
$("#fb-root").on("facebook:init", function(event, response) {
if(response.status === 'connected') {
alert("logged with FB")
}else{
alert("No Logged with FB")
}
});
Chargez le script de manière dynamique (ajoutez une balise de script à partir de js) et recherchez les événements d'erreur/de succès.