Skip to content

Instantly share code, notes, and snippets.

@jacob-ebey
Created January 11, 2023 00:53
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacob-ebey/e4d35711c901cf313bcce854ad028f1f to your computer and use it in GitHub Desktop.
Save jacob-ebey/e4d35711c901cf313bcce854ad028f1f to your computer and use it in GitHub Desktop.
Navigation and View Transition API example
import { html } from "html-tagged";
export default function ClientNavigation() {
return html`
<script type="module">
if (typeof navigation !== "undefined") {
let lastAbortController;
navigation.addEventListener("navigate", (event) => {
if (!event.canIntercept) return;
if (lastAbortController) {
lastAbortController.abort();
}
lastAbortController = new AbortController();
const signal = lastAbortController.signal;
event.intercept({
async handler() {
const transition = document.createDocumentTransition();
signal.addEventListener("abort", () => {
transition.abandon();
});
if (signal.aborted) return;
const response = await fetch(event.destination.url, {
signal,
});
if (signal.aborted) return;
const newHTML = await response.text();
if (signal.aborted) return;
if (!document.createDocumentTransition) {
updateDOM(newHTML);
return;
}
transition.start(() => updateDOM(newHTML));
await transition.finished;
},
});
});
}
function updateDOM(newHTML) {
const htmlElement = document.createElement("html");
htmlElement.innerHTML = newHTML;
const existingScripts = new Set();
let childNodesLength = document.body.childNodes.length;
for (let i = childNodesLength - 1; i >= 0; i--) {
if (document.body.childNodes[i].tagName === "SCRIPT") {
existingScripts.add(document.body.childNodes[i].innerHTML);
continue;
}
document.body.removeChild(document.body.childNodes[i]);
}
const bodyChildren = htmlElement.querySelector("body").childNodes;
childNodesLength = bodyChildren.length;
for (let i = childNodesLength - 1; i >= 0; i--) {
if (
bodyChildren[i].tagName === "SCRIPT" &&
existingScripts.has(bodyChildren[i].innerHTML)
) {
continue;
}
document.body.prepend(bodyChildren[i]);
}
scrollTo(0, 0);
}
</script>
`;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment