[javascript] Facebook Likeボタンの幅を自動的に変更するにはどうしたらいいですか?



3 Answers

誰もが今知っているように、これを行う簡単な方法はありません。 しかし、私は一種のプログラム的な不器用さを思いついた。 そして、私がkludgeと言うとき、私は本当にそれを意味します! 私はこれをプライムタイムに向けて準備しているとは考えていませんが、誰かがそのコンセプトを試してみて、実行可能なものを見つけようと思っているかもしれません。

アイデアは、iframeのコンテンツの幅を読み取ることはできませんが、iframe自体の一連の幅をループすることができます。 その時点で、テキストはiframeの右側に接触する必要があります。 言い換えれば、iframeの幅を、テキストを折り返す幅より1px広い幅に設定したいとします。

テキストが折り返しかどうかを検出することは原理的には簡単です。iframeの幅を設定し、FBコードが内容を調整するのを待ってから高さを読み取ります。 すべてが1行に収まる場合は、高さは約25ピクセルにする必要があります。 それ以上は、テキストが折り返されていることを意味します。

難しさは、 "FBコードがコンテンツを調整するのを待つ"という部分があります。 iframeを強制的に再描画する必要があるような気がしますが、これまで見つけられていません。 FB.XFBML.parse()を呼び出すことは明らかですが、動作しないようです。 これは私が立ち往生した部分です。 私はiframeに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>
Question

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

ドキュメントによると、デフォルトの幅は450です。 これで大丈夫ですが、 <fb:like>タグのwidth属性でwidth変更できることを理解しています。 しかし、私の問題は、実際には固定幅を指定できないことです。 ボタンの性質上、幅はすべての状態で一定ではありません。 たとえば、誰もそのページを気に入っていない人がいれば、「これを好きな人の最初の友人になる」と表示されます。 誰かが持っている場合、それは "このようなXXXの人があなたの友人の一人になる"と表示します。 あなたがそれを好きだったとしても、それは「You like this」 または 「You and XXX people like this」と表示されます。 つまり、ボタンには多くの状態があり、いずれも一定の幅を共有していません。

<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)ボタン領域のすべてを右揃えにします。

誰でも私を与えることができる任意のおかげで、ありがとう!




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

#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ボタンが置かれていて、それが私のエッジと揃っていて、追加されたコメント(幅のダイナミック)だけがエッジを越えて表示されます。 長さにかかわらず、コメントを表示しながら良いデザインを保つことができます。




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

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

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



CSS修正

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



Related