Как изменить iframe родительской стороны на всю высоту дочерней стороны SAPUI5?

Моя цель — реализовать мой веб-сайт 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.


62
1

Ответ:

Решено

Судя по вашим комментариям, вам нужен надежный момент времени, когда 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, '*');
  }
}