31

I'm implementing the Facebook Like Button, but I'm running into some trouble with the width. I'm using the JavaScript SDK implementation, not the direct iframe.

According to the documentation, the default width is 450. That's fine, and I understand that the width can be changed by way of the width attribute on the <fb:like> tag. However, my problem is that I really cannot specify a fixed width. Due to the nature of the button, the width is not constant in all states. For example, if no one has liked the page yet it displays "Be the first of your friends to like this"; if someone has, it displays "XXX people like this. Be the first of your friends"; and still if you have liked it, it displays "You like this" or "You and XXX people like this." In other words, there are many states of the button, none of which share a constant width.

This wouldn't be much of a problem if it weren't for the fact that I want to display the button floated on the right-hand side of a <div>. To be clearer, this is what I'm doing:

<div id="wrapper">
    <span class="fb-like"><fb:like show_faces="false" width="450" font="lucida grande""></fb:like></span>
    ...
</div>
<style type="text/css">
.fblike {
    display: inline-block;
    padding: 0.5em;
    position: absolute;
    right: 0;
    top: 0;
}
#wrapper {
    position: relative;
}
</style>

This works fine, but the problem is that the iframe now has a constant width of 450 pixels. Since the iframe is left-aligned, when the text is shorter there is extra space to the right. I've tried various applications of text-align: right to no avail. And the problem is further compounded by the fact that this is really just fancy markup for an iframe that is added by the FB SDK, so I'm powerless to change any of its contents with CSS or JavaScript.

I need a solution that will either (a) keep the width of the button area dynamic (i.e., it changes according to the content); or (b) right-align everything in the button area.

Thanks for any help anyone can give me!

4

8 回答 8

14
#fblike iframe {
    width: 95px !important;
}

#fblike .fb_edge_comment_widget iframe {
    width: 330px !important;
}

<div id="fblike"><fb:like show-faces="false" layout="button_count"></fb:like></div>

这样评论和点赞按钮 iframe 的宽度都是固定的。没有有趣的效果。希望能帮助到你。

于 2011-01-28T10:59:16.483 回答
5

如果您使用 XFBML 版本的 Like 按钮以及 Facebook Javascript SDK,您可以订阅“xfbml.render”事件,一旦该事件触发,您可以将 like 按钮 iframe 的宽度设置为一些较小的值. (我使用 50px。)然后 iframe 将根据需要自动调整其宽度,以便根据您的配置显示按钮和点赞数以及任何其他元素。

https://developers.facebook.com/docs/reference/javascript/

此解决方案的最大障碍是您需要一个 Facebook App ID。您可以通过在此处创建应用程序来获取应用程序 ID:https ://developers.facebook.com/apps/

于 2012-04-08T13:53:56.637 回答
5

到目前为止,每个人都可能知道,没有简单的方法可以做到这一点。不过,我确实想出了一种程序化的组合。当我说kludge时,我是认真的!我认为这还没有为黄金时段做好准备,但有人可能想修改这个概念并尝试找到可行的东西。

这个想法是,虽然您无法读取 iframe 的内容宽度,但您可以遍历 iframe 本身的一系列宽度,直到找到一个几乎不能阻止内部文本换行的宽度。此时,文本必须接触 iframe 的右侧。换句话说,我们希望将 iframe 的宽度设置为比导致文本换行的宽度宽 1px。

原则上检测文本是否换行很容易——设置 iframe 宽度,等待 FB 代码调整内容,然后读取高度。如果所有内容都适合一行,则高度应约为 25px。不仅如此,还意味着文本已换行。

困难在于“等待FB代码调整内容”部分。我觉得必须以某种方式强制 iframe 的“重绘”,但到目前为止我还没有找到它。调用 FB.XFBML.parse() 很明显,但它似乎不起作用。这是我卡住的部分。我通过设置它的 src 属性来强制 iframe 重新加载,它可以完成这项工作,但速度却非常糟​​糕。在这一点上,它只是作为“概念证明”。知道任何重绘何时完成的简单方法几乎同样好;我觉得这也应该是可能的,但在我发现任何简单的事情之前,我的大脑就陷入了困境。

无论如何,如果您想尝试一下,这里有一些测试代码。将按钮固定到位需要很长时间,但它至少可以工作。我在加载过程中让所有东西都可见,这样你就可以看到它在做什么,在真实页面上最好把东西隐藏起来,直到一切都准备好。另请注意,对齐可能会稍微偏离,因为我一次调整宽度 5px。如果事情可以做得更快,那么使用 1px 会很容易。更好的可能是粗略调整以接近,然后进行微调以使其完美。显然,对于任何想要接受它的人来说,要做很多实验。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type='text/javascript'>
var likediv, likeframe;
function loadcode(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/all.js#xfbml=1";
  fjs.parentNode.insertBefore(js, fjs);
}
function init()
{
loadcode(document, 'script', 'facebook-jssdk');
likediv=document.getElementById('d2');
setTimeout(initx, 10);
}
function initx()
{
likeframe=likediv.getElementsByTagName('iframe')[0];
if (!likeframe) { setTimeout(initx, 10); return; }
likeframe.style.width='225px';
setTimeout(shrink, 10);
}
function shrink()
{
likeframe=likediv.getElementsByTagName('iframe')[0];
var currwidth=parseInt(likeframe.style.width);
if (currwidth>=500) return;
newwidth=currwidth+5;
likeframe.style.width=newwidth+'px';
likeframe.style.height='0';
likeframe.src=likeframe.src;
setTimeout(checkframe, 10);
}
function checkframe()
{
var h=parseInt(likeframe.offsetHeight);
if (h==0) setTimeout(checkframe, 10);
else if (h>25) shrink();
//else we are done; make the frame visible if we hid it earlier
}
</script>
</head>
<body onload='init()' style='margin:10px 50px'>
<div id="fb-root"></div>
<div style='text-align:right'>Here is some right-aligned text to compare to.</div>
<div id='d2' style='float:right;height:25px;overflow:hidden;border:1px dotted red'>
<div class="fb-like" data-send="false" data-width="225" data-show-faces="false" data-action="recommend"></div>
</div>
</body>
</html>

编辑:做了更多的实验,仍然是一个尴尬的解决方法,但比以前更快:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type='text/javascript'>
var likediv, likeframe, targwidth;
function loadcode(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/all.js#xfbml=1";
  fjs.parentNode.insertBefore(js, fjs);
}
function init()
{
loadcode(document, 'script', 'facebook-jssdk');
likediv=document.getElementById('d2');
setTimeout(initx, 10);
}
function initx()
{
likeframe=likediv.getElementsByTagName('iframe')[0];
if (!likeframe) { setTimeout(initx, 10); return; }
likeframe.style.width='225px';
setTimeout(shrink, 10);
}
function shrink()
{
likeframe=likediv.getElementsByTagName('iframe')[0];
var currwidth=parseInt(likeframe.style.width);
if (currwidth>=500) return;
targwidth=currwidth+5;
likeframe.style.width='10px';
likeframe.style.height='0';
setTimeout(checkframe, 10);
}
function checkframe()
{
var h=parseInt(likeframe.offsetHeight);
if (h==0) { setTimeout(checkframe, 10); return; }
likeframe.style.width=targwidth+'px';
likeframe.style.height='0';
setTimeout(checkframe2, 10);
}
function checkframe2()
{
var h=parseInt(likeframe.offsetHeight);
if (h==0) setTimeout(checkframe2, 10);
else if (h>25) shrink();
//else we are done; make the frame visible if we hid it earlier
}
</script>
</head>
<body onload='init()' style='margin:10px 50px'>
<div id="fb-root"></div>
<div style='text-align:right'>Here is some right-aligned text to compare to.</div>
<div id='d2' style='float:right;height:25px;overflow:hidden;border:1px dotted red'>
<div class="fb-like" data-send="false" data-width="225" data-show-faces="false" data-action="recommend"></div>
</div>
</body>
</html>

最终编辑:这是我认为这种方法所能得到的最好的;代码当然可以调整,但总是需要几秒钟才能通过试验宽度来找到有效的方法。但它现在已经足够快(大约 5 秒),它实际上可能是可用的。顺便说一句,我正在添加每个新的代码版本而不是替换旧的代码版本,因为我没有对此代码进行太多的跨浏览器测试,而且高速版本可能不适用于某人。由于这都是实验性代码,我认为最好有不同的版本可用于后备。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type='text/javascript'>
var minwidth=225, maxwidth=500, finished=false, last_was_good=null;
var likediv, likeframe, targwidth, boundlow, boundhigh;
function loadcode(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/all.js#xfbml=1";
  fjs.parentNode.insertBefore(js, fjs);
}
function init()
{
loadcode(document, 'script', 'facebook-jssdk');
likediv=document.getElementById('d2');
setTimeout(initx, 10);
}
function initx()
{
likeframe=likediv.getElementsByTagName('iframe')[0];
if (!likeframe) { setTimeout(initx, 10); return; }
likeframe.style.width=minwidth+'px';
setTimeout(trynewwidth, 1);
}
function trynewwidth()
{
if (last_was_good==null) { boundlow=minwidth; boundhigh=maxwidth; }
else if (last_was_good) boundhigh=targwidth;
else boundlow=targwidth;
finished=((boundhigh-boundlow)<2);
if (finished && last_was_good) { done(); return; }
if (finished && !last_was_good) targwidth=boundhigh;
else targwidth=parseInt((boundlow+boundhigh)/2);
setTimeout(setwidth, 1);
}
function done()
{
//All finished, if we were hiding the div make it visible now
}
function setwidth()
{
likeframe=likediv.getElementsByTagName('iframe')[0];
likeframe.style.width='10px';
likeframe.style.height='0';
setTimeout(checkframe, 10);
}
function checkframe()
{
var h=parseInt(likeframe.offsetHeight);
if (h==0) { setTimeout(checkframe, 10); return; }
likeframe.style.width=targwidth+'px';
likeframe.style.height='0';
setTimeout(checkframe2, 10);
}
function checkframe2()
{
var h=parseInt(likeframe.offsetHeight);
if (h==0) { setTimeout(checkframe2, 10); return; }
if (finished) { done(); return; }
last_was_good=(h<26);
setTimeout(trynewwidth, 1);
}
</script>
</head>
<body onload='init()' style='margin:10px 50px'>
<div id="fb-root"></div>
<div style='text-align:right'>Here is some right-aligned text to compare to.</div>
<div id='d2' style='float:right;height:25px;overflow:hidden;border:1px dotted red'>
<div class="fb-like" data-send="false" data-width="225" data-show-faces="false" data-action="recommend"></div>
</div>
</body>
</html>
于 2011-10-12T18:35:09.033 回答
3

CSS 修复

.fb-like, 
.fb-like > span,
.fb-like > span iframe {
    max-width:273px;
}
于 2012-08-25T09:23:04.113 回答
2

在选择尺码时,有一些常见问题解答值得一读。

https://developers.facebook.com/docs/plugins/like-button

尽管话虽如此,但它仍然很神秘:

“插件的宽度。您选择的布局会影响您可以使用的最小和默认宽度,有关详细信息,请参阅下面的常见问题解答。”

标准

最小宽度:225 像素。

如果操作是“推荐”,则最小值增加 40 像素,如果发送为“真”,则最小值增加 60 像素。

默认宽度:450 像素。高度:35 像素(不含照片)或 80 像素(含照片)。

box_count

最小宽度:55 像素。默认宽度:55 像素。高度:65 像素。

button_count

最小宽度:90 像素。默认宽度:90 像素。高度:20 像素。

按钮

最小宽度:47 像素。默认宽度:47 像素。高度:20 像素。

于 2014-05-20T07:57:03.027 回答
2

我个人使用以下...

#fbook-like {
    width: 50px !important; /*width of just the button*/
    overflow: visible; /*so there is no cut off*/
    vertical-align: top; /*bc all other like buttons align top*/
}

我在这里所做的是将 fb 按钮放在最右边,使其与我的边缘对齐,并且仅添加的评论(宽度动态)将显示在边缘之外。无论长度如何,我都能在获得评论的同时保持良好的设计。

于 2012-09-08T22:22:30.437 回答
0

I had to face this same problem with the add-this plugin and solved in a similar way:

.addthis_button_facebook_like,
.addthis_button_facebook_like span,
.addthis_button_facebook_like span iframe {
    max-width: 450px !important;
}
于 2014-04-02T14:29:43.033 回答
0

我将此添加到我的 CSS 中:

div.fb-like.fb_iframe_widget > span {
 width: 100% !important;
}

div.fb-like.fb_iframe_widget{
 width: 100%;
}
于 2016-05-11T12:21:43.950 回答