Active Element
Web Components ⟩ Shadow DOM ⟩ Events ⟩
Google ⟩ Web Component ⟩ Handling focus
events that are fired inside shadow DOM are adjusted to look like they come from the hosting element.
<x-focus>
#shadow-root
<input type="text" placeholder="input inside shadow dom">
Active Element in Shadow DOM
// ⭐️ if you click <input> inside a shadow root,
// the `focus` event will look like it came from <x-focus>,
// not the <input>❗️
document.activeElement // ⭐️ <x-focus>
// ⭐️ only works with {mode: open}.
document.activeElement.shadowRoot.activeElement // ⭐️ <input>
Active Element down Multiple Levels of Shadow DOM
If there are multiple levels of shadow DOM at play (say a custom element within another custom element), you need to recursively drill into the shadow roots to find the activeElement:
function deepActiveElement() {
// top-level active element
let a = document.activeElement;
// recursively drill into shadow roots to find activeElement
while (a && a.shadowRoot && a.shadowRoot.activeElement) {
a = a.shadowRoot.activeElement;
}
// return the real active element
return a;
}
{delegatesFocus: true}
💾 replit
// outer DOM events (⭐️ 收不到 `focus` 訊號❓)
document.body.addEventListener('focus', e => {
let tag = document.activeElement.nodeName;
console.log(`Active element (outer DOM): ${tag}`);
})
// main
function log(msg){
const div = document.querySelector('my-log');
div.log(msg);
}
Last updated
Was this helpful?