Как все, вероятно, уже знают, нет простого способа сделать это. Однако я придумал своего рода программный кладж. И когда я говорю кладж, я действительно имею это в виду! Я не считаю это готовым для прайм-тайма, но кому-то может понравиться повозиться с концепцией и попытаться найти что-то работоспособное.
Идея состоит в том, что, хотя вы не можете прочитать ширину содержимого iframe, вы можете перебрать серию значений ширины для самого iframe, пока не найдете тот, который едва предотвращает перенос текста внутри. В этот момент текст должен касаться правой стороны iframe. Другими словами, мы хотим установить ширину iframe на 1 пиксель шире, чем ширина, при которой текст будет обтекаться.
Определить, переносится ли текст, в принципе достаточно просто — вы устанавливаете ширину iframe, ждете, пока код FB отрегулирует содержимое, а затем считываете высоту. Если все помещается в одну строку, высота должна быть около 25 пикселей. Более того, это означает, что текст завернут.
Трудность связана с частью «подождите, пока код FB настроит контент». Я чувствую, что должен быть какой-то способ принудительно «перерисовать» iframe, но пока я его не нашел. Вызов FB.XFBML.parse() очевиден, но, похоже, он не работает. Это та часть, где я застрял. Я заставляю iframe перезагружаться, устанавливая его атрибут src, который выполняет свою работу, но с ужасной ценой скорости. На данный момент это просто означает «доказательство концепции». Почти таким же хорошим был бы простой способ узнать, когда любая перерисовка завершена; Я чувствую, что это тоже должно быть возможно, но мой мозг увяз, прежде чем я нашел что-нибудь простое.
В любом случае, вот некоторый тестовый код, если вы хотите попробовать. Чтобы привести кнопку в нужное положение, требуется вечность, но, по крайней мере, она работает. Я оставил все видимым во время процесса загрузки, чтобы вы могли видеть, что он делает, на реальной странице было бы лучше держать вещи скрытыми, пока все не будет готово. Также обратите внимание, что выравнивание может быть немного неправильным, потому что я настраиваю ширину по 5 пикселей за раз. Если бы все можно было сделать быстрее, вместо этого было бы легко использовать 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>
person
Floyd Wilburn
schedule
12.10.2011