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