Моя цель — реализовать мой веб-сайт SAPUI5 в iframe, размер которого изменяется до полной высоты содержимого iframe. Веб-сайт, содержащий iframe, находится на другом сервере.
Как передать всю высоту веб-сайта родительской странице? В примерах используется сайт localhost вместо исходного. Используемая версия платформы SAPUI5 — 1.120.
Мои первые попытки были полностью расчетами на родительской стороне, которые не работали из-за политики перекрестного доступа к DOM. В данный момент я не могу изменить эту политику. Попытки, показанные ниже, являются более поздними реализациями, поскольку я потерял код первой попытки.
-- Это была вторая попытка. Он работает со страницами, которые не созданы с помощью платформы SAPUI5. Полученный размер дочернего элемента SAPUI5 всегда равен текущей высоте iframe.
Родительская сторона:
<script>
window.addEventListener('message', receiveMessage, false);
function receiveMessage(size){
resizeIFrameToFitContent(size.data);
}
function resizeIFrameToFitContent(size){
document.getElementById("exampleFrame").style.height = size;
}
</script>
Детская сторона:
function postPageSize(){
size = window.document.body.scrollHeight + "px";
window.parent.postMessage(size, '*');
}
-- Была также попытка использования интервала и более или менее «динамического» изменения размера страницы. Здесь я получаю сообщение об ошибке «Uncaught DOMException: доступ к свойству «документ» объекта перекрестного происхождения запрещен», которая в настоящее время неразрешима для меня.
Родительская сторона:
<script>
setInterval(function(){
var pageHeight = document.getElementById("exampleFrame").contentWindow.document.body.offsetHeight;
}, 1000)
</script>
-- Последняя попытка была немного более сложной и использовала некоторые собственные функции. Это также возвращает текущий размер iframe. Следует отметить, что этот код работает на более старой веб-странице, созданной с использованием платформы SAP.
Родительская сторона:
<script>
window.addEventListener('message', e=>{if (e.origin= = "http://localhost"){
var iFr = document.getElementById("exampleFrame")
if (iFr && iFr.style.height != e.data) iFr.style.height = e.data
}})
</script>
<iframe src = "http://localhost/path/to/page" id = "exampleFrame" style = "height:500px"></iframe>
Детская сторона:
function ensureIFrameResizingFor(MainCont){
setInterval(function(){
var pgId = MainCont.getCurrentPage().getId() //MainCont is our usual App- or Navigation-Container (which holds "Pages")
var hFrm = 0, hHdr = 0
var hdr = document.querySelector("#" + pgId + " .sapMPageHeader")
if (hdr) hHdr = parseInt("0" + getComputedStyle(hdr).getPropertyValue("height"))
var frm = document.querySelector("#" + pgId + " .sapUiSimpleForm")
if (!frm){
hHdr = 3*hHdr
frm = document.querySelector("#" + pgId + " .sapUiTableVSbContent") //fallback (second attempt, in case the Page is a Listing-Page)
if (!frm) frm = document.querySelector("#" + pgId + " .sapMListTblCnt")
}
if (frm) hFrm = parseInt("0" + getComputedStyle(frm).getPropertyValue("height"))
//console.info(hFrm, hHdr)
if (hFrm) top.postMessage((hFrm + hHdr + 18) + "px", PostMsg_CallbackURL)
}, 500)
}
Обновлено: Получил решение. Мне нужно было извлечь «scrollHeight», выполнив поиск, где обрабатывается полоса прокрутки. Затем функция управляется setInterval, поскольку некоторые элементы на сайте изменяются динамически.
Это готовая дочерняя функция:
function sendSizeToParent(){
if (document.getElementsByClassName("sapMPageEnableScrolling")[0].scrollHeight != null){
var height = document.getElementsByClassName("sapMPageEnableScrolling")[0].scrollHeight
if (window.parent){
window.parent.postMessage(height, '*');
}
}
}
🤔 А знаете ли вы, что...
JavaScript можно использовать для создания ботов и автоматизации задач в браузерах с помощью Puppeteer.
Судя по вашим комментариям, вам нужен надежный момент времени, когда sap.m.Page
завершил рендеринг, чтобы вы могли затем сообщить родительской странице о высоте.
Изучив документацию SAP UI 5, сводка sap.m.Page показывает, что Page
имеет возможность добавить метод onAfterRendering
, который он заимствует из sap.ui.core.Control. Согласно документации, этот метод автоматически вызывается после завершения процесса рендеринга.
Поэтому я бы предложил:
На родительской странице вы в основном делаете то же, что и до сих пор:
window.addEventListener('message', (event) => {
document.getElementById('exampleFrame').style.height = `${event.data}px`;
});
Код внутри iframe должен использовать .postMessage
внутри метода onAfterRendering
, тогда:
// please adjust accordingly
onAfterRendering() {
const height = document.body.scrollHeight;
if (window.parent) { // only post if placed inside an iframe
window.parent.postMessage(height, '*');
}
}
Помните, что вам необходимо определить onAfterRendering
в своем экземпляре sap.m.Page
. Возможно, вам придется настроить показанный пример кода в соответствии с остальной частью вашего кода, например:
page.onAfterRendering = function() {
const height = document.body.scrollHeight;
if (window.parent) { // only post if placed inside an iframe
window.parent.postMessage(height, '*');
}
}