Come regolare automaticamente l'altezza dell'iframe per i post di WordPress incorporati

Mi stavo chiedendo questo da un po’. Ecco una prova di concetto (nota che non risolve il problema della rimozione delle barre di scorrimento dagli iframe).

Aggiungi un tag script al post che stai incorporando:

<script>
    function sendHeight() {
        const body = document.body,
            html = document.documentElement;

        const height = Math.max(body.scrollHeight, body.offsetHeight,
            html.clientHeight, html.scrollHeight, html.offsetHeight);

        window.parent.postMessage({
            'iframeHeight': height,
            'iframeId': 'zalgFrame' // Usa un identificatore univoco se hai più iframe
        }, '*'); // Considera la specifica del dominio padre per la sicurezza
    }

    // Invia l'altezza iniziale
    window.onload = sendHeight;

    // Opzionale: aggiorna l'altezza al ridimensionamento o ad altri eventi
    window.onresize = sendHeight;
</script>

Sto usando l’identificatore "zalgFrame" nello script.

Nel tuo tema Discourse:

<script type="text/discourse-plugin" version="1.29.0">
let iframeHeight, iframeId;
window.addEventListener('message', (event) => {
  if (event.origin !== "http://wp-discourse.test") return; // il mio dominio di test, aggiornalo al tuo dominio o commentalo
  // ottiene l'altezza dell'iframe passata da `wp-discourse.test` e conferma che iframeId corrisponde all'iframeID che ho impostato lì
  if (event.data.iframeHeight && event.data.iframeId === 'zalgFrame') {
      // visita la pagina Discourse con l'iframe con la console aperta
      // dovresti vedere le altezze aggiornate inviate dal sito padre mentre ridimensioni la finestra
      console.log("abbiamo ricevuto un evento:" + event.data.iframeHeight);
      iframeHeight = event.data.iframeHeight;
      iframeId = event.data.iframeId;
  }
  }, false);
</script>

In un post di Discourse:

<div data-iframe-test-one>
<iframe src="http://wp-discourse.test/zalg_iframe/this-is-a-test-this-is-only-a-test/" width="100%" height="1659"></iframe>
</div>

Quindi è possibile ottenere l’altezza effettiva dell’iframe renderizzato dalla finestra padre.

Non so come ottenere l’altezza dai dati dal listener di eventi in una chiamata a api.decorateCookedElement. Non sono sicuro che funzionerebbe per rimuovere la barra di scorrimento verticale dagli iframe lunghi. Se provo a codificare un’altezza elevata (1600px) nell’elemento iframe, finisco ancora con una barra di scorrimento.

Modifica: per completezza:

<script type="text/discourse-plugin" version="1.29.0">
api.decorateCookedElement(
  (e) => {
    let iframeHeight, iframeId;

    function handleMessage(event) {
      if (event.origin !== "http://wp-discourse.test") return;
      if (event.data.iframeHeight && event.data.iframeId === "zalgFrame") {
        iframeHeight = event.data.iframeHeight;
        iframeId = event.data.iframeId;
        // basato sull'assunzione che ci sarà solo 1 iframe racchiuso nel div data-zalgFram
        let iframe = e.querySelector("[data-zalgFrame] iframe");
        if (iframe) {
          iframe.style.height = `${iframeHeight}px`;
        }
        // dopo aver impostato l'altezza effettiva renderizzata dell'iframe
        // rimuovi il listener di eventi
        window.removeEventListener("message", handleMessage, false);
      }
    }
    window.addEventListener("message", handleMessage, false);
  },
  { id: "component-id", onlyStream: true }
);
</script>

Per qualsiasi altezza superiore a ~1000px, non sembra esserci alcun modo per evitare che Discourse aggiunga una barra di scorrimento, quindi non consiglio questo approccio.

Penso che la risposta all’OP sia che è in qualche modo possibile, ma probabilmente non porta molto lontano. (Tranne che ho imparato il metodo window.postMessage() :slight_smile: