Creating a pop-out iframe with adoptNode and "magic iframes"

Mise à jour: 8 octobre - Problèmes importants avec ce doc.

J'ai rattrapé Jake Archibald propos de ce post parce que je pensais avoir quelque chose de nouveau. Au cours de la conversation, nous avons découvert beaucoup de choses qui rendent certains de ces posts invalides, et j'ai également beaucoup appris au cours du processus que la plupart des développeurs ne pensent pas connaître.

  • L'appel de .append() et .appendChild() adopte le nœud. Cela rend l'utilisation de adoptNode dans cette instance inutile car l'algorithme append garantit que le nœud est adopté. Cela n'a pas été mentionné dans la documentation MDN, mais dans le spec . J'ai besoin de revenir en arrière et de m'entraîner pour savoir pourquoi j'avais un problème plus tôt, mais je suppose que c'est parce que j'essayais à l'origine d'ajouter un DocumentFragment . Cela signifie que w.document.body.appendChild(document.adoptNode(airhornerIframe)); et w.document.body.appendChild(airhornerIframe); auront le même effet.
  • Bien que les éléments DOM conservent leur état (cochez l'élément personnalisé), si un iframe est déplacé dans le DOM, il est rechargé. Période. Cela signifie que le déplacer entre iframes ne gardera pas l'état comme je l'avais testé à l'origine, je pense que cela était dû au fait que le SW chargeait la page incroyablement rapidement. Cela n'affectera peut-être pas l'API des portails - cette expérience devrait donc fonctionner à l'avenir :)

Le concept de déplacement d'éléments entre documents est toujours valable et intéressant, mais l'avantage pour iframes n'existe pas. J'ai remarqué que les éléments vidéo ont été réinitialisés lorsqu'ils ont été déplacés d'une fenêtre à l'autre et que j'aurais dû faire plus attention en vérifiant que l'iframe ne réinitialise pas réellement son état.

Comme toujours, vous pouvez voir le commit history for this post .

Original post Lorsque j'ai rejoint Google en 2010, je suis tombé sur un document qui mentionnait un concept dans gmail appelé " magic iframes ". magic iframes nom était cool et le concept était nouveau.

  • Targeted at apps with multiple windows
  • All code and data go into an IFRAME
  • If window hosting the IFRAME unloads, it gets adopted by another of the windows
  • In Gmail for example:
    • Tearoff / pop-out compose creates bare window that is filled by code in IFRAME in main window
    • If you close the main window, the code looks for a tear-off that can accept the IFRAME and moves it
    • You finish your compose and can still send the email
  • Old way: create new instance of Gmail tailored to the task.

Le concept est que beaucoup d'applications doivent charger beaucoup de JavaScript complexe même pour un "petit composant" tel que la fenêtre de composition dans gmail, vous pouvez charger les composants de l'application dans un iframe lequel l'utilisateur peut interagir dans la fenêtre principale. que vous pouvez ensuite "déchirer" et passer à une nouvelle fenêtre lorsque vous cliquez sur le bouton "composer dans une nouvelle fenêtre". Je n'avais pas assez confiance en moi pour parler à l'auteur (et je ne l'ai toujours pas fait, pas plus que je n'ai regardé la source de gmail pour voir s'il a déjà été utilisé), mais cela est resté dans ma mémoire surtout parce que le nom était énigmatique. .

adoptNode je faisais un long trajet en train et j'ai commencé à enquêter sur un domaine que je ne connaissais pas beaucoup au sujet de l’API adoptNode . J'ai joué avec un lot of ideas et j'ai réalisé qu'il était possible de déplacer des éléments DOM, leur état actuel et leurs gestionnaires d'événements attachés dans de nouvelles fenêtres. Cela m’a rappelé les «iframes magiques» et a finalement conduit à l’idée que vous pouvez créer un iframe sortant (un iframe sortant est une vidéo Picture in Picture mais pour des éléments iframe).

Le code de l'iframe sortant est assez simple:

<iframe src="https://airhorner.com" id="airhorner"> </iframe>

<button id="adoptIframeButton">
  Popout iframe into new window (adoptNode)
</button>

<script>
 adoptIframeButton.addEventListener("click", () => {
    const airhornerIframe = document.getElementById("airhorner");
    const width = airhornerIframe.clientWidth;
    const height = airhornerIframe.clientHeight;
    const w = window.open("blank.html", "", `top=100,width=${width},height=${height}`);
    w.addEventListener("load", () => {
      w.document.body.appendChild(airhornerIframe);
    });
 });
</script>

adoptNode vous permet de déplacer les éléments DOM avec leur état actuel tout en conservant leurs gestionnaires d'événements liés existants, entre les documents du navigateur. Il peut s'agir d'un nouveau DOM dans la fenêtre actuelle ou, dans le cas de cette démonstration, déplacer un élément déjà existant. chargé iframe dans une autre fenêtre ayant la même origine. (Voir mise à jour ci-dessus).

Déplacer une iframe est intéressant car cela signifie que vous n'avez pas à redémarrer le contenu de l'iframe, l'instance est simplement déplacée. Il y a quelques inconvénients:

  1. L'URL reste sur l'origine actuelle et non sur l'iframe, bien que l'API <portal> puisse résoudre ce problème.
  2. Si vous déplacez un élément personnalisé ou quelque chose dont la logique est hébergée sur l'ouvre-porte - si vous fermez l'ouvre-porte, l'exécution sera interrompue.

Inconvénients mis à part, je pensais que ce mécanisme IPC de niveau DOM était très très intéressant. Amusez-vous avec demo page ( src ) et src -moi si vous avez des idées intéressantes pour savoir où cela pourrait être utilisé.

Paul Kinlan

Trying to make the web and developers better.

RSS Github Medium