Reputation: 3898
On our blog we have a link where users can post our articles to their timeline. A popup opens up and the user posts to facebook, then the popup stays there and redirects to "www.oursite.com". How do we instead close the popup when the user either finishes posting or clicks on the cancel button? According to this so question it can't be done but Huffington post has figured it out but looking at their code we can't figure it out. As an example, the facebook share button here will open up a popup and then close when you either post the article or cancel.
Here's what we have:
FB.init({appId: "90210", status: true, cookie: true});
function postToFeed() {
// calling the API ...
var obj = {
method: 'feed',
redirect_uri: 'http://www.oursite.com/',
link: 'http://www.oursite.com/',
picture: 'http://www.oursite.com/png.png',
name: 'Some title',
caption: '',
description: ''
};
function callback(response){
window.close(); // doesn't do anything
//document.getElementById('msg').innerHTML = "Post ID: " + response['post_id'];
}
FB.ui(obj, callback);
}
We've tried adding window.close(); in the callback (and also self.close();), tried leaving redirect_uri blank (and tried leaving redirect_uri out altogether, but it's required).
Upvotes: 8
Views: 17110
Reputation: 861
As of 10/2017 removing redirect_uri
seems to work.
It will default to https://www.facebook.com/dialog/return/close#_=_
whose source is just
<script type="text/javascript"> window.close() </script>
Upvotes: 4
Reputation: 31
UPDATE: Add this script to your redirect page:
if (document.referrer == "https://www.facebook.com/" && (window.location.href.indexOf('post_id=') != -1 || window.location.hash == '#_=_')) {
window.close();
}
Upvotes: 3
Reputation: 6832
This is not a direct answer to the original question, but it might help others arriving here.
There is a more robust way to do this that allows you take action on the originating page when the share has completed successfully:
In the originating page:
var shareWindow;
function openShareWindow() {
// See https://developers.facebook.com/docs/sharing/reference/share-dialog
shareWindow = window.open('https://www.facebook.com/dialog/share?app_id=...&display=popup&redirect_uri=...');
}
function shareCompleted() {
if (shareWindow) {
shareWindow.close();
shareWindow = null;
// The share was successful, so do something interesting here...
}
}
In the page you have set as your redirect_uri
, which I usually map to something like http://myserver.com/share/close
:
window.opener.shareCompleted();
Now you're assured the share window will close and you'll be able to take action on the originating page if needed.
Note: shareCompleted
must be available in the root window namespace for this work. If you're wrapping all of your JavaScript as you should be, then be sure to:
window.shareCompleted = shareCompleted;
Upvotes: 1
Reputation: 367
<script>if (window.location.hash.indexOf("#close_window") != -1) window.close();</script>
Upvotes: 0
Reputation: 2114
After spending a whole day working on this problem, I have a very good solution that I'd like to share. Instead of using the SDK with FB.ui(), I have discovered that I can avoid it entirely by manually opening my own popup to https://www.facebook.com/dialog/feed. When doing it this way, redirect_uri works as expected. As long as you require the user to click a button to make the dialog pop up, no popup blocker will be triggered.
I don't believe there are any compromises with this code, and if anything, it is much easier to use than the actual SDK.
My Javascript code (which you can save as FacebookFeedDialog.js) looks like this:
/* by Steven Yang, Feb 2015, originally for www.mathscore.com. This code is free for anybody to use as long as you include this comment. */
function FacebookFeedDialog(appID, linkTarget, redirectTarget) {
this.mParams = {
app_id: appID,
link: linkTarget,
redirect_uri: redirectTarget,
display: "popup"
}
};
/* Common params include:
name - the title that appears in bold font
description - the text that appears below the title
picture - complete URL path to the image on the left of the dialog
caption - replaces the link text
*/
FacebookFeedDialog.prototype.addParam = function(key, value) {
this.mParams[key] = value;
};
FacebookFeedDialog.prototype.open = function() {
var url = 'https://www.facebook.com/dialog/feed?' + encodeCGIArgs(this.mParams);
popup(url, 'feedDialog', 700, 400);
};
/* Takes a param object like this:
{ arg1: "value1", arg2: "value2" }
and converts into CGI args like this:
arg1=value1&arg2=value2
The values and args will be properly URI encoded
*/
function encodeCGIArgs(paramObject) {
var result = '';
for (var key in paramObject) {
if (result)
result += '&';
result += encodeURIComponent(key) + '=' + encodeURIComponent(paramObject[key]);
}
return result;
}
function popup(mylink,windowname,width,height) {
if (!window.focus) return;
var href;
if (typeof(mylink) == 'string')
href=mylink;
else
href=mylink.href;
if (!windowname)
windowname='mywindow';
if (!width)
width=600;
if (!height)
height=350;
window.open(href, windowname, 'resizable=yes,width='+width+',height='+height+',scrollbars=yes');
}
Here's a sample HTML file that uses the Javascript code above:
<HTML>
<BODY>
<SCRIPT type="text/javascript" src="FacebookFeedDialog.js"></SCRIPT>
<SCRIPT>
var dialog = new FacebookFeedDialog(yourAppIDGoesHere,yourDestinationURLGoesHere,yourCloseWindowURLGoesHere);
dialog.addParam('name','This is my title');
dialog.addParam('description','This is the description');
dialog.addParam('picture',yourImageURLGoesHere);
dialog.addParam('caption','This is the caption');
</SCRIPT>
<A href="javascript:dialog.open()">Open facebook dialog</A>
</BODY>
</HTML>
Your closeWindow html file can look like this:
<SCRIPT>
window.close();
</SCRIPT>
Upvotes: 8
Reputation: 984
It seems that the accepted answer is no longer working due to the fact that facebook now strips anything after a hash and replaces it with post_id=xxxxx.
Solution #1 (if you trust FB not to change this in the near future):
if(window.location.search.indexOf('post_id')==1) window.close();
Solution #2 (if you want a little more insurance against change and don't mind a second file): Create a new html file closewindow.html:
<html><body><script>window.close()</script></body></html>
and link to it in the redirect.
Upvotes: 17
Reputation: 24342
Redirect to http://oursite.com/#close_window. Then on your site's homepage, include something like this:
if (window.location.hash == '#close_window') window.close();
.
Upvotes: 15