Iframes projected to slots. Iframes won't reload.

This fiddle demonstrates how when the target of a projection of an iframe is moved around, the iframe itself doesn't reload.

by David Iglesias

HTML

<div id='rotate'>
  <button data-direction='down'>Iframe ⬆️</button>
  <button data-direction='up'>Iframe ⬇️</button>
</div>

<div id='target'>
</div>

<p>
The iframe is now rendered in a stable position in the DOM, and instead it's displayed through a <tt>slot</tt> tag. The <tt>slot</tt> is inside the <tt>shadowDOM</tt> of the target element, and the iframe is a sibling of the shadow root. The slot can be moved around, and <strong>the iframe won't reload.</strong>
</p>

CSS

/* Nothing on this stylesheet matters, this is just eye candy. */
* { font-family: sans-serif; box-sizing: border-box; }
tt { font-family: monospace; background-color: #eee; }

.filler {
  background: #fabada;
  border: 1px solid black;
  text-align: center;
}
iframe {
  width: 100%;
  height: 200px;
  border: 1px solid black;
  margin: 0px;
}
#rotate {
  margin: 10px 0px;
  text-align: center;
}

JavaScript

const targetDiv = document.querySelector('#target');
const target = targetDiv.attachShadow({mode: 'open'});

// Clone the CSS from the outside...
const css = document.querySelector('#compiled-css').cloneNode(true);
target.appendChild(css);

// Inject some filler divs...
for(let i=0; i < 3; i++) {
	const div = document.createElement('div');
  div.className = 'filler';
  div.innerHTML = i;
  target.appendChild(div);
}

// Inject a slot...
const slot = document.createElement('slot');
slot.name = 'iframe-target';
target.appendChild(slot);

// Inject an iframe...
const iframe = document.createElement('iframe');
iframe.src = 'https://www.flutter.dev/';
iframe.slot = 'iframe-target';

targetDiv.appendChild(iframe);

const rotate = document.querySelector('#rotate');
rotate.addEventListener('click', (event) => {
  // Don't move the css tag around :)
  const children = [...target.children].filter((el) => el !== css);
	const firstChild = children[0];
  const direction = event.target.dataset.direction;
  if (direction === 'up') {
    // Move Last to First
    const lastChild = children[children.length-1];
    target.insertBefore(lastChild, firstChild);
  } else if (direction === 'down') {
    // Move First to Last
    target.appendChild(firstChild);
  }
});