如何让Facebook Like按钮的宽度自动调整大小?

时间:2010-12-03 17:36:41

标签: javascript css facebook facebook-like facebook-javascript-sdk

我正在实施Facebook Like Button,但我遇到了宽度问题。我正在使用JavaScript SDK实现,而不是直接iframe。

根据文档,默认宽度为450。这没关系,我知道宽度可以通过width标签上的<fb:like>属性进行更改。但是,我的问题是我真的无法指定固定宽度。由于按钮的性质,宽度在所有状态下都不是恒定的。例如,如果没有人喜欢该页面,它会显示“成为您喜欢的第一个朋友”;如果有人,它显示“XXX这样的人。成为你的第一个朋友”;并且如果喜欢它,它会显示“你喜欢这个”“你和XXX的人喜欢这个。”换句话说,按钮有很多状态,没有一个共享一个恒定的宽度。

如果不是因为我想显示浮动在<div>右侧的按钮,这不是什么大问题。为了更清楚,这就是我正在做的事情:

<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>

这很好用,但问题是iframe现在有一个450像素的恒定宽度。由于iframe是左对齐的,因此当文本较短时,右侧会有额外的空间。我尝试了text-align: right的各种应用程序无济于事。而这个问题更加复杂的是,这实际上只是FB SDK添加的iframe的奇特标记,所以我无力用CSS或JavaScript更改其任何内容。

我需要一个解决方案,它将(a)保持按钮区域的宽度动态(即,它根据内容而改变);或(b)右键对齐按钮区域中的所有内容。

感谢任何人都能给我的帮助!

8 个答案:

答案 0 :(得分:12)

#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都是固定宽度。没有搞笑的效果。希望它有所帮助。

答案 1 :(得分: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>

答案 2 :(得分:5)

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

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

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

答案 3 :(得分:2)

CSS修复

.fb-like, 
.fb-like > span,
.fb-like > span iframe {
    max-width:273px;
}

答案 4 :(得分: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按钮放在最右边,因此它与我的边缘对齐,只是添加的注释(动态宽度)将显示超过边缘。无论长度如何,我都可以在收到评论的同时保持良好的设计。

答案 5 :(得分:2)

在选择尺寸时,有一些值得阅读的常见问题答案。

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

尽管如此,它仍然非常神秘:

  

“插件的宽度。您选择的布局会影响最小值   您可以使用默认宽度,请参阅下面的常见问题解答了解更多信息   方式“。

标准

  

最小宽度:225像素。

     

最低增加40px如果   如果send为'true',则动作为“推荐”并增加60px。

     

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

box_count

  

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

button_count

  

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

按钮

  

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

答案 6 :(得分:0)

我不得不面对add-this插件的同样问题,并以类似的方式解决:

.addthis_button_facebook_like,
.addthis_button_facebook_like span,
.addthis_button_facebook_like span iframe {
    max-width: 450px !important;
}

答案 7 :(得分:0)

我将此添加到我的CSS:

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

div.fb-like.fb_iframe_widget{
 width: 100%;
}