Как сделать так, чтобы ширина кнопки «Нравится» на Facebook автоматически изменялась? - PullRequest
31 голосов
/ 03 декабря 2010

Я использую 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 безрезультатно. И проблема еще больше усугубляется тем фактом, что это действительно просто причудливая разметка для iframe, добавляемого FB SDK, поэтому я бессильна изменить любое его содержимое с помощью CSS или JavaScript.

Мне нужно решение, которое будет либо: (а) сохранять ширину области кнопки динамической (то есть она изменяется в зависимости от содержимого); или (b) выровняйте по правому краю все в области кнопок.

Спасибо за любую помощь, кто может мне помочь!

Ответы [ 8 ]

12 голосов
/ 28 января 2011
#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>

Таким образом, фреймы комментариев и кнопок лайков имеют фиксированную ширину. Никаких забавных эффектов. Надеюсь, это поможет.

5 голосов
/ 08 апреля 2012

Если вы используете XFBML-версию кнопки «Нравится» вместе с Javascript SDK Facebook, вы можете подписаться на событие «xfbml.render», и после того, как это событие сработает, вы можете установить ширину кнопки «Нравится» iframe на какое-то небольшое значение. (Я использую 50px.) Затем iframe автоматически отрегулирует свою ширину по мере необходимости, чтобы отобразить кнопки и т.п., а также другие элементы в соответствии с вашей конфигурацией.

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

Самым большим препятствием для этого решения является то, что вам потребуется идентификатор приложения Facebook. Вы можете получить идентификатор приложения, создав приложение здесь: https://developers.facebook.com/apps/

5 голосов
/ 12 октября 2011

Как все, наверное, уже знают, простого способа сделать это не существует. Я все же придумал что-то вроде программной кучи. И когда я говорю kludge, я действительно имею это в виду! Я не считаю это готовым к прайм-тайму, но кто-то может захотеть поработать с концепцией и попытаться найти что-то работоспособное.

Идея состоит в том, что, хотя вы не можете прочитать ширину содержимого iframe, вы можете циклически проходить серию ширин для самого iframe до тех пор, пока не найдете тот, который едва препятствует переносу текста внутри. На этом этапе текст должен касаться правой стороны фрейма. Другими словами, мы хотим установить ширину iframe на 1px шире, чем ширина, которая приведет к переносу текста.

Определение того, является ли текст переносом, в принципе достаточно простое - вы устанавливаете ширину iframe, ждете, пока код FB отрегулирует содержимое, и затем считываете высоту. Если все умещается на одной линии, высота должна быть около 25 пикселей. Больше, чем это означает, что текст обернут.

Сложность возникает из-за того, что вы ждете, пока код FB настроит содержимое. Я чувствую, что должно быть что-то, чтобы вызвать «перерисовку» iframe, но пока я не нашел его. Вызов FB.XFBML.parse () очевиден, но, похоже, не работает. Это та часть, где я застрял. Я заставляю iframe перезагружаться, устанавливая его атрибут src, который делает работу, но по ужасной цене в скорости. Это просто означает «доказательство концепции» на данный момент. Почти так же хорошо было бы простым способом узнать, когда перерисовка была закончена; Я чувствую, что это также возможно, но мой мозг застрял, прежде чем я нашел что-то простое.

В любом случае, здесь есть тестовый код, если вы хотите попробовать. Требуется целая вечность, чтобы получить кнопку в положении, но это по крайней мере работает. Я оставил все видимым во время процесса загрузки, чтобы вы могли видеть, что он делает, на реальной странице было бы лучше держать вещи скрытыми, пока все не будет готово. Также обратите внимание, что выравнивание может быть немного смещено, потому что я регулирую ширину 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 голосов
/ 20 мая 2014

Есть несколько ответов на часто задаваемые вопросы, которые стоит прочитать при выборе размера.

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

Хотя при этом сказано, что все еще довольно загадочно:

«Ширина плагина. Выбранный вами макет влияет на минимальную ширину и ширину по умолчанию, которые вы можете использовать, для получения более подробной информации см. Ниже FAQ».

стандарт

Минимальная ширина: 225 пикселей.

Минимальное увеличение на 40px, если действие «рекомендовать», и увеличение на 60px, если send «true».

Ширина по умолчанию: 450 пикселей.Высота: 35 пикселей (без фотографий) или 80 пикселей (с фотографиями).

box_count

Минимальная ширина: 55 пикселей.Ширина по умолчанию: 55 пикселей.Высота: 65 пикселей.

button_count

Минимальная ширина: 90 пикселей.Ширина по умолчанию: 90 пикселей.Высота: 20 пикселей.

кнопка

Минимальная ширина: 47 пикселей.Ширина по умолчанию: 47 пикселей.Высота: 20 пикселей.

2 голосов
/ 09 сентября 2012

Я лично использую следующее ...

#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 в крайнее правое положение, чтобы она совпала с моим краем, и только добавленные комментарии (динамические по ширине) будут показываться за краем. Я могу сохранять хороший дизайн, получая комментарии, независимо от длины.

2 голосов
/ 25 августа 2012

CSS fix

.fb-like, 
.fb-like > span,
.fb-like > span iframe {
    max-width:273px;
}
0 голосов
/ 11 мая 2016

Я добавил это в свой CSS:

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

div.fb-like.fb_iframe_widget{
 width: 100%;
}
0 голосов
/ 02 апреля 2014

Мне пришлось столкнуться с той же проблемой с плагином add-this и решить аналогичным образом:

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