web-dev-qa-db-ja.com

Facebookの「いいね」ボタンの幅を自動的にサイズ変更するにはどうすればよいですか?

Facebook Like Button を実装していますが、幅に問題があります。直接のiframeではなく、JavaScript SDK実装を使用しています。

ドキュメントによると、デフォルトの幅は450です。それで結構です。<fb:like>タグのwidth属性を使用して幅を変更できることを理解しています。しかし、私の問題は、固定幅を実際に指定できないことです。ボタンの性質上、幅はすべての状態で一定ではありません。たとえば、誰もそのページをまだ気に入っていない場合は、「これがあなたの友達の中で一番好きになる」と表示されます。誰かが持っている場合は、「このような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)ボタン領域のすべてを右揃えにします。

誰もが私を与えることができる助けをありがとう!

31
Josh Leitzel
#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は固定幅です。面白い効果はありません。それが役に立てば幸い。

12

おそらく誰もが知っているように、これを行う簡単な方法はありません。けれども、私はある種の計画的なクラッジを思いついた。そして私がkludgeを言うとき、私は本当にそれを意味します!私はこれをプライムタイムの準備ができているとは考えていませんが、誰かがコンセプトをいじくり回して何か実行可能なものを見つけようとするかもしれません。

アイデアは、iframeのコンテンツの幅を読み取ることはできませんが、内部のテキストの折り返しをほとんど妨げないものを見つけるまで、iframe自体の一連の幅をループできるということです。その時点で、テキストはiframeの右側に接触している必要があります。つまり、iframeの幅を、テキストを折り返す幅よりも1px広く設定したいと考えています。

テキストが折り返されているかどうかの検出は、原則として十分簡単です。iframeの幅を設定し、FBコードがコンテンツを調整するのを待ってから、高さを読み取ります。すべてが1行に収まる場合、高さは約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秒)です。ところで、私はこのコードのクロスブラウザテストをあまり行っていないため、新しいコードバージョンを1つずつ追加するので、高速バージョンが機能しない可能性があります。これはすべて実験的なコードなので、フォールバックに使用できるさまざまなバージョンを用意することをお勧めします。

<!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>
5
Floyd Wilburn

XFBMLバージョンの「いいね!」ボタンをFacebook JavaScript SDKとともに使用する場合、「xfbml.render」イベントをサブスクライブし、そのイベントが発生したら、「いいね!」ボタンのiframeの幅を小さな値に設定できます。 (私は50pxを使用します。)iframeは、ボタンやカウントなどの要素を構成に応じて表示するために、必要に応じて幅を自動調整します。

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

このソリューションの最大の障害は、FacebookアプリIDが必要になることです。ここでアプリを作成すると、アプリIDを取得できます。 https://developers.facebook.com/apps/

5
Pascal

サイズを選択するときに読む価値のあるいくつかのFAQ回答があります。

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

とはいえ、それはまだかなり不可解です:

「プラグインの幅。選択したレイアウトは、使用できる最小幅とデフォルト幅に影響します。詳細については、FAQを参照してください。 "

標準

最小幅:225ピクセル。

最小値は、アクションが「推奨」の場合は40px増加し、送信が「true」の場合は60px増加します。

デフォルトの幅:450ピクセル。高さ:35ピクセル(写真なし)または80ピクセル(写真あり)。

box_count

最小幅:55ピクセル。デフォルトの幅:55ピクセル。高さ:65ピクセル。

button_count

最小幅:90ピクセル。デフォルトの幅:90ピクセル。高さ:20ピクセル。

ボタン

最小幅:47ピクセル。デフォルトの幅:47ピクセル。高さ:20ピクセル。

2
Simon_Weaver

私は個人的に以下を使用しています...

#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ボタンを配置することです。これにより、ボタンがEdgeに合わせられ、追加されたコメント(幅が動的)だけがEdgeを越えて表示されます。長さに関係なく、コメントを表示しながら、良いデザインを維持することができます。

2
Jacob Thomason

CSS修正

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

私はこれを私のCSSに追加しました:

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

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

私はadd-thisプラグインでこの同じ問題に直面し、同様の方法で解決する必要がありました:

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