简体   繁体   English

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

[英]How can I make the Facebook Like button's width automatically resize?

I'm implementing the Facebook Like Button , but I'm running into some trouble with the width. 我正在实现Facebook Like Button ,但我遇到了宽度问题。 I'm using the JavaScript SDK implementation, not the direct iframe. 我正在使用JavaScript SDK实现,而不是直接iframe。

According to the documentation, the default width is 450 . 根据文档,默认宽度为450 That's fine, and I understand that the width can be changed by way of the width attribute on the <fb:like> tag. 那没关系,我明白宽度可以通过<fb:like>标签上的width属性来改变。 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"; 如果有人,它显示“XXX这样的人。成为你的第一个朋友”; and still if you have liked it, it displays "You like this" or "You and XXX people like this." 如果喜欢它,它会显示“你喜欢这个” “你和XXX这样的人”。 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> . 如果不是因为我想显示浮动在<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. 这工作正常,但问题是iframe现在具有450像素的恒定宽度 Since the iframe is left-aligned, when the text is shorter there is extra space to the right. 由于iframe是左对齐的,因此当文本较短时,右侧会有额外的空间。 I've tried various applications of text-align: right to no avail. 我尝试过text-align: right各种应用程序text-align: right没有用。 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. 而这个问题更加复杂的是,这实际上只是FB SDK添加的iframe的花哨标记,所以我无力用CSS或JavaScript更改其任何内容。

I need a solution that will either (a) keep the width of the button area dynamic (ie, it changes according to the content); 我需要一个解决方案,它将(a)保持按钮区域的宽度动态(即,它根据内容而改变); or (b) right-align everything in the button area. 或(b)右键对齐按钮区域中的所有内容。

Thanks for any help anyone can give me! 感谢任何人都可以给我的帮助!

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

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

And

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

This way both comment and like button iframes are fixed width. 这样,注释和类似按钮iframe都是固定宽度。 No funny effects. 没有搞笑的效果。 Hope it helps. 希望能帮助到你。

If you use the XFBML version of the Like button, along with the Facebook Javascript SDK, you can subscribe to the 'xfbml.render' event, and once that event fires, you can set the width of the like button iframe to some small value. 如果您使用Like按钮的XFBML版本以及Facebook Javascript SDK,您可以订阅'xfbml.render'事件,并且一旦该事件触发,您可以将like按钮iframe的宽度设置为某个小值。 (I use 50px.) The iframe will then auto-adjust its width as needed in order to display button and like count and whatever other elements, according to your config. (我使用50px。)iframe将根据需要自动调整其宽度,以便根据您的配置显示按钮和类似计数以及其他任何元素。

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

The biggest obstacle to this solution is that you will need a Facebook App ID. 此解决方案的最大障碍是您需要Facebook App ID。 You can get an App ID by creating an app here: https://developers.facebook.com/apps/ 您可以在此处创建应用程序来获取应用程序ID: https//developers.facebook.com/apps/

As everyone probably knows by now, there is no easy way to do this. 正如大家现在所知道的那样,没有简单的方法可以做到这一点。 I did come up with a programatic kludge of sorts, though. 不过,我确实想出了各种各样的程序设计。 And when I say kludge, I really mean it! 当我说kludge时,我真的是这个意思! I do not consider this ready for prime time, but someone may like to tinker with the concept and try to find something workable. 我不认为这是准备黄金时间,但有人可能喜欢修补这个概念,并尝试找到可行的东西。

The idea is that although you can't read the content width of the iframe, you can loop through a series of widths for the iframe itself until you find one that just barely prevents the text inside from wrapping. 我们的想法是,虽然您无法读取iframe的内容宽度,但您可以遍历iframe本身的一系列宽度,直到找到一个几乎不会阻止文本内部包装的宽度。 At that point, the text must touching the right-hand side of the iframe. 此时,文本必须触及iframe的右侧。 In other words, we want to set the width of the iframe to 1px wider than the width that would cause the text to wrap. 换句话说,我们希望将iframe的宽度设置为比导致文本换行的宽度宽1px。

Detecting whether the text is wrapping is easy enough in principle -- you set the iframe width, wait for the FB code to adjust the content, and then read the height. 原则上检测文本是否包装很容易 - 设置iframe宽度,等待FB代码调整内容,然后读取高度。 If everything fit on one line, the height should be about 25px. 如果一切都适合一条线,高度应约为25px。 More than that means the text has wrapped. 更重要的是文本已经包装。

The difficulty comes with the "wait for the FB code to adjust the content" part. 困难在于“等待FB代码调整内容”部分。 I feel like there must be someway to force a "redraw" of the iframe, but so far I haven't found it. 我觉得必须有一些强制“重绘”iframe,但到目前为止我还没有找到它。 Calling FB.XFBML.parse() is obvious, but it doesn't seem to work. 调用FB.XFBML.parse()是显而易见的,但它似乎不起作用。 This is the part where I got stuck. 这是我卡住的部分。 I'm forcing the iframe to reload by setting its src attribute, which does the job but at a horrible price in speed. 我通过设置src属性来强制iframe重新加载,这样可以完成工作但速度非常可怕。 It is just meant as "proof of concept" at this point. 在这一点上,它只是作为“概念证明”。 Almost as good would be a simple way to know when any redraw was finished; 几乎同样好的方法是知道什么时候重绘完成; I feel that should also be possible but my brain bogged down before I found anything simple. 我觉得这也应该是可能的,但在我发现任何简单的事情之前,我的大脑陷入困境。

Anyway here is some test code if you want to give it a try. 无论如何,这里有一些测试代码,如果你想尝试一下。 It takes forever to get the button in position, but it does at least work. 按钮处于适当位置需要永远,但它至少可以工作。 I left everything visible during the loading process so you can see what it's doing, on a real page it would be better to keep things hidden until everything is ready. 我在加载过程中保留了所有可见内容,因此您可以看到它正在做什么,在真实页面上最好保持隐藏状态直到一切准备就绪。 Also note that the alignment may be slightly off because I am adjusting the width 5px at a time. 另请注意,对齐可能稍微偏离,因为我一次调整宽度为5px。 If things could be made faster it would be easy to use 1px instead. 如果事情可以更快地完成,那么使用1px会很容易。 Even better would probably be a rough adjustment to get close, then a fine adjustment to get it perfect. 更好的可能是近距离的粗略调整,然后进行微调以使其完美。 Obviously lots of experimenting to do, for whoever might want to take it up. 对于那些想要接受它的人来说,显然有很多尝试要做。

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

EDIT: Did a little more experimenting, still an awkward workaround but faster than before: 编辑:做了一些实验,仍然是一个尴尬的解决方法,但比以前更快:

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

FINAL EDIT: This is the best I think this method is ever going to get; 最终编辑:这是我认为这种方法最好的方法; the code could certainly be tweaked but it's always going to take several seconds to run through the trial widths to find what works. 代码肯定可以调整,但是总是需要几秒钟才能通过试验宽度来找到有效的方法。 But it's now quick enough (around 5 seconds) that it might actually be usable. 但它现在足够快(大约5秒),它实际上可以使用。 BTW I am adding each new code version rather than replacing the old ones because I haven't done much cross-browser testing of this code and it's possible the higher-speed versions won't work for someone. 顺便说一句,我正在添加每个新的代码版本,而不是替换旧版本,因为我没有对此代码进行过多次跨浏览器测试,并且高速版本可能无法为某些人工作。 Since it's all experimental code I think it's better to have the different versions available for fallback. 由于它是所有实验代码,我认为最好让不同的版本可用于后备。

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

CSS fix CSS修复

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

I'm personally using the following... 我个人使用以下内容......

#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*/
}

What I've done here is put the fb button on the far right and so it aligns with my edge, and just the comments added (dynamic in width) will show past the edge. 我在这里做的是将fb按钮放在最右边,这样它与我的边缘对齐,只是添加的注释(动态宽度)将显示超过边缘。 I'm able to keep a good design while getting the comments showing, regardless of the length. 无论长度如何,我都可以在收到评论的同时保持良好的设计。

There are some FAQ answers that are worth reading when choosing a size. 在选择尺寸时,有一些值得阅读的FAQ答案。

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

Although with that said it's still pretty cryptic : 虽然说它仍然很神秘:

"The width of the plugin. The layout you choose affects the minimum and default widths you can use, please see the FAQ below for more details." “插件的宽度。您选择的布局会影响您可以使用的最小和默认宽度,请参阅下面的常见问题解答以获取更多详细信息。”

standard 标准

Minimum width: 225 pixels. 最小宽度:225像素。

Minimum increases by 40px if action is 'recommend' by and increases by 60px if send is 'true'. 如果“推荐”操作,则最小增加40px,如果发送为“true”,则增加60px。

Default width: 450 pixels. 默认宽度:450像素。 Height: 35 pixels (without photos) or 80 pixels (with photos). 高度:35像素(无照片)或80像素(带照片)。

box_count box_count

Minimum width: 55 pixels. 最小宽度:55像素。 Default width: 55 pixels. 默认宽度:55像素。 Height: 65 pixels. 高度:65像素。

button_count button_count

Minimum width: 90 pixels. 最小宽度:90像素。 Default width: 90 pixels. 默认宽度:90像素。 Height: 20 pixels. 高度:20像素。

button 按键

Minimum width: 47 pixels. 最小宽度:47像素。 Default width: 47 pixels. 默认宽度:47像素。 Height: 20 pixels. 高度:20像素。

I had to face this same problem with the add-this plugin and solved in a similar way: 我不得不面对add-this插件的同样问题,并以类似的方式解决:

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

I added this to my CSS: 我把它添加到我的CSS中:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM