Комментарии 45
Всё круто, но ифреймы… как-то я сомневаюсь, что они прям уж так необходимы для организации виджетов. Js-api и дивы милее сердцу.
Собственно, изначально разрабатывал для того, чтобы довести до ума виджеты в Piwik — они там были сначала флешовые — было проще, потом они сделали рендеринг всех графиков без флеша и соответственно виджеты стали в iframe.
Нужно было с минимальными затратами сделать, чтобы вставленные на страницы сайта виджеты из статистики (у меня пивик используется в качестве инструмента статистики для поддоменов пользователей) выглядели нормально и автоматически ресайзились под размер.
Тратить свое время на переписывание движка виджетов в пивике в данный момент я не готов, а написать 2 небольших js-файла, которые надо просто подключить и все становится как хочется — почему нет.
Может еще кому пригодится (в piwik я уже отправил патч)
Нужно было с минимальными затратами сделать, чтобы вставленные на страницы сайта виджеты из статистики (у меня пивик используется в качестве инструмента статистики для поддоменов пользователей) выглядели нормально и автоматически ресайзились под размер.
Тратить свое время на переписывание движка виджетов в пивике в данный момент я не готов, а написать 2 небольших js-файла, которые надо просто подключить и все становится как хочется — почему нет.
Может еще кому пригодится (в piwik я уже отправил патч)
Если у вас виджет запускается через яваскрипт — то если тот сайт, с которого он запускается взломали — считайте и ваш также взломали (ну либо виджет со стрёмного ресурса взяли). Можно будет сделать любые изменения на вашей странице и, кроме того, вытянуть куки пользователя.
Если сделать window.parent у ифрэйма, который с другого домена — бравзер ругнётся.
Если сделать window.parent у ифрэйма, который с другого домена — бравзер ругнётся.
ифреймы… как-то я сомневаюсь, что они прям уж так необходимы для организации виджетов. Js-api и дивы милее сердц
При необходимости размещать защищённые данные в виджетах на чужих доменах иного решения просто нет. Если вы разместите виджет в диве и примете с сайта виджета защищённые данные с каким угодно шифрованием, тело виджета должно содержать расшифровку, следовательно, данные будут уже не защищены от взлома и использования третьими лицами.
При размещении в фрейме вы спокойно работаете с данными и выдаёте наружу только результат, через мембрану фрейма, по postMessage. Защита, разумеется не от пользователя, а от вирусных скриптов, к которым пользователь отношения не имеет. Если его страница заражена, через фрейм скрипты не проберутся, данные виджета будут в безопасности. С дивами этого добиться невозможно.
Iframe будет жить всегда. Также, как и два бессмертных элемента верстки и <br />.
В xhtml нет там  
НЛО прилетело и опубликовало эту надпись здесь
я таких не встречал, Opera как натыкается начинает всю страницу парсить как html, a FF вовсе отказываются отображать страницу.
НЛО прилетело и опубликовало эту надпись здесь
Ну например вот мои
home.poofeg.ru/test/test.xhtml
home.poofeg.ru/test/test.xhtml
Лично я вместо пробела пользую распорку (прозрачный gif 1х1px или растягиваю его до нужных мне размеров).
очень пригодилось. спасибо!
Спасибо огромное! Как раз была проблема смены высоты фрейма в зависимости от содержимого.
Переписал код на основной странице на jQuery и добавил animate(). Пока что не видел проблем с погрешностью все ресайзится точно.
если пользоваться jQuery на дочерней странице то погрешности и не должно быть
Хм, почему-то вот это вот:
не заработало в ОгнеЛисе. Такое ощущение, что Firefox не умеет window.frames['frame_id']. Переписал так:
pm({
target: window.frames[frame.id],
type: "register",
data: {id:frame.id},
url: frame.contentWindow.location
});
не заработало в ОгнеЛисе. Такое ощущение, что Firefox не умеет window.frames['frame_id']. Переписал так:
var target = undefined;
for (var i=0; i<window.frames.length;i++){
if (window.frames[i].frameElement == frame){
target = window.frames[i];
break;
}
}
pm({
target: target,
type: "register",
data: {id:frame.id},
url: frame.contentWindow.location
});
В яндексе можно найти множество решений этой проблемы, но большинство из них обладают одной проблемой: они не поддерживают возможность менять размеры окна когда содержимое iframe и родительский элемент находятся на разных доменах.
Видимо искать лучше в гугле, потому что когда мне надо было какое-то кроссдоменное решение, я нашёл это:
benalman.com/code/projects/jquery-postmessage/examples/iframe/
По сути то же самое, что и у вас (postMessage с фоллбеком на location.hash), только сделано 3 года назад :)
По сути тоже самое, но требует jQuery в дочернем и родительском документе.
Мое решение обходится без него (хотя конечно присутствие jQuery в дочернем документе упрощает дело)
Мое решение обходится без него (хотя конечно присутствие jQuery в дочернем документе упрощает дело)
Ну и еще мое решение лучше тем, что позволяет без обработки напильником расположить на странице любое количество фреймов — достаточно кажому iframe прописать id, name и зарегистрировать (FrameManager.registerFrame(this)) его.
Но все равно спасибо за ссылку.
Но все равно спасибо за ссылку.
Я делал реализацию на postMessage + хак с window.opener в старых ослах (как реализовано в Open Social). Соответственно, никаких таймаутов, хешей, 1 скрипт на все страницы.
К сожалению, не знаком с Open Social. Поделитесь информацией с хаком window.opener?
Таймаут нужен для отслеживания изменения высоты документа внутри фрейма, насколько мне известно, по-другому это никак не отследишь — onresize срабатывает при изменении размеров окна, а не документа.
Таймаут нужен для отслеживания изменения высоты документа внутри фрейма, насколько мне известно, по-другому это никак не отследишь — onresize срабатывает при изменении размеров окна, а не документа.
Хак заключается в том, что осел позволяет менять свойство opener объекта window у созданного фрейма:
Соответственно, из фрейма делаем уже кроссбраузерный вызов:
Причем, как советует гугл, объект для opener лучше создавать через vbscript из-за соображений безопасности (каких конкретно не помню):
Ну а window._onMessage присваивается как opener в созданные фреймы.
iframe.contentWindow.opener = {
postMessage: function (data, domain){};
};
Соответственно, из фрейма делаем уже кроссбраузерный вызов:
window.opener.postMessage('data', '*');
Причем, как советует гугл, объект для opener лучше создавать через vbscript из-за соображений безопасности (каких конкретно не помню):
function onMessage(evt, domain) {}; // Обработчик postMessage, в осле evt == evt.data
window._onMessage = onMessage;
window.execScript(
'Private onMessage\n' +
'Class PostMsg\n' +
'Public Sub postMessage(data, domain)\n' +
'Call onMessage(data, domain)\n' +
'End Sub\n' +
'End Class\n' +
'Set onMessage = window._onMessage\n' +
'Set window._onMessage = New PostMsg', 'vbscript');
Ну а window._onMessage присваивается как opener в созданные фреймы.
Аналогичное решение на юзерскрипте делалось в HabrAjax для кнопки Google Plus для передачи количества «лайков» наружу. Кто заинтересуется, может скрипт там посмотреть, он без сторонних библиотек типа postMessage.js, всё на виду. А вообще, планирую на этой неделе написать статью (уже написана) по этой же теме с проекцией на юзерскрипты, потому что из-за них в Хроме есть баг передачи данных через фрейм, который там обойдён.
#site1
document.domain = 'com'
#site2
document.domain = 'com'
document.domain = 'com'
#site2
document.domain = 'com'
Таким скриптом вы можете очень хорошо положить #site1, особенно если он вам не принадлежит. Вот сделали такую глупость, а потом вебмастер #site1 не может понять, почему в IE он создаёт frame, пытается к нему достучаться и получает Security Exception.
по какой причине не может достучаться? Все может.
и можно делать domain='com' только при выполнении условия каких либо
и можно делать domain='com' только при выполнении условия каких либо
Вот прекрасное обсуждение: stackoverflow.com/questions/1886547/access-is-denied-javascript-error-when-trying-to-access-the-document-object-of
И ты уже не можешь достучаться к динамически созданному IFrame'у.
document.domain = document.domain;
И ты уже не можешь достучаться к динамически созданному IFrame'у.
это только IE касается чтоли? меня ie вообще никоим образом не интересует.
IE пользуется значительная часть интернет обывателей. Так что когда речь идёт о массовых и кроссбраузерных решениях, то что конкретно вас ie не интересует, никого больше не интересует.
Не замеряли быстродействие такого метода? Сколько времени занимает один сеанс запрос-ответ между айфреймами? Например, у Facebook JS SDK есть проблема, что фенкция запроса параметров из iFrame занимает от 500мс и до бесконечности (FB.Canvas.getInfo), что очень замедляет работу приложения.
НЛО прилетело и опубликовало эту надпись здесь
Один из самых интересных моментов в этой задаче — общение между доменами, вы скинули на отдельную библиотеку, остальное достаточно просто, и задачу эту не раз уже решали в любом сервисе, который так или иначе держит у себя внешние приложения. См, например метод gadgets.window.adjustHeight в opensocial вообще и в apache shindig в частности. Интереснее было бы, если бы вы предложили архитектуру для предоставления API фреймам внутри сайта для общения с контейнером.
Так postMessage это фактически и есть простая обертка (API), позволяющая общаться фреймам внутри сайта с контейнером, а также окнам браузера между собой.
Задачу решать-то решали, но вот найти решение в открытом доступе было достаточно сложно (например, если я никогда не пользовался opensocial — откуда мне знать, что я там смогу найти ответ на мой вопрос?)
Теперь решение есть, и судя по количеству добавлений в избранное — оно достаточно востребованное.
Задачу решать-то решали, но вот найти решение в открытом доступе было достаточно сложно (например, если я никогда не пользовался opensocial — откуда мне знать, что я там смогу найти ответ на мой вопрос?)
Теперь решение есть, и судя по количеству добавлений в избранное — оно достаточно востребованное.
Как вообще изменить высоту этого iframe на iPad?
В нём он всегда растягивается по высоте содержимого и никак иначе =(
В нём он всегда растягивается по высоте содержимого и никак иначе =(
В яндекс виджетах это, кстати, тоже както решено, но без подключения js в дочерние файлы:
api.yandex.ru/wdgt/doc/apiref/reference/widget-adjustiframeheight.xml
api.yandex.ru/wdgt/doc/apiref/reference/widget-adjustiframeheight.xml
Кстати о нем habrahabr.ru/post/83083/
Классный метод взаимодействия между iframe-ми. Спасибо за статью и пример. Очень помогло.
postmessage.freebaseapps.com
Выдаёт 404. Обновите ссылочку в статье?.. :)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Автоматическая кросс-доменная установка высоты Iframe