Front-End News: setHTML() and Element.startViewTransition
An interactive tour of two new DOM features: safe HTML insertion with sanitization, and scoped view transitions on individual elements.
1. Default setHTML() Sanitization vs setHTMLUnsafe()
Code:
const str = `<script>console.log('Oh no, hit by Blade Shield');</script>
<img class="inline-demo-image" src="${demoImage}" onload="this.style.border = '3px solid #dc2626'; this.nextElementSibling.textContent = 'onload ran';">
<small>onload has not run</small>
<details>
<summary>HTML is not simple</summary>
<p>Thank you all for supporting the正版 edition. Never stop learning.</p>
</details>
<p>Does plain text not show either?</p>`;
setHTMLButton.onclick = () => {
if (container.setHTML) {
container.setHTML(str);
} else {
container.innerHTML = "<p>Does plain text not show either?</p>";
}
};
unsafeButton.onclick = () => {
if (container.setHTMLUnsafe) {
container.setHTMLUnsafe(str);
} else {
container.innerHTML = str;
}
};
Result:
Click either button to insert the same HTML string.
2. Custom Sanitizer Options
Code:
const sanitizer = new Sanitizer({
removeElements: ["script"],
removeAttributes: ["onload"]
});
customButton.onclick = () => {
if (containerWithRules.setHTML && window.Sanitizer) {
containerWithRules.setHTML(str, { sanitizer });
} else {
const template = document.createElement("template");
template.innerHTML = str;
template.content.querySelectorAll("script").forEach((node) => node.remove());
template.content.querySelectorAll("[onload]").forEach((node) => node.removeAttribute("onload"));
containerWithRules.replaceChildren(template.content);
}
};
Result:
Only the script element and onload attribute are removed; the image and details element remain.
3. Element.startViewTransition() for Scoped Removal
Code:
removeWithTransition.onclick = () => {
const card = transitionContainer.querySelector(".removing");
if (transitionContainer.startViewTransition) {
transitionContainer.startViewTransition(() => {
card.remove();
});
} else {
card.remove();
}
};
Result:
The transition is started on the container element, so the animation scope stays local to this showcase.
One
Remove me
Three
Click remove to compare abrupt DOM removal with scoped view-transition behavior where supported.