确定从父元素继承的区域设置更改



我正在尝试编写一个区域设置感知的自定义元素。为了格式化其输出,它会查找自身及其父元素lang属性,navigator.languageUI 本地化回退到浏览器。

format (d, m, s) {
const lang = (this.closest('[lang]') || document.querySelector('html')).lang;
let list = navigator.languages;
try {
list = Intl.getCanonicalLocales(lang);
} catch (e) {}
const format = new Intl.NumberFormat(list, {
maximumFractionDigits: 2
}).format;
return `${d}° ${m}′ ${format(Math.round(s * 100) / 100)}″`;
}

每次组件更改其值时,这将为我提供最佳信息。但它不包括在运行时更改lang属性的情况。如果组件本身的属性发生了变化,我可以观察到它的变化:

static get observedAttributes() { return ['lang']; }
attributeChangedCallback (name, oldValue, newValue) {
if (name === 'lang') // trigger re-rendering
}

但是,如果更改发生在父元素甚至继承设置的浏览器 UI 上,我将如何检测更改?

MutationObserver似乎是一个尴尬的选择:我必须将其附加到父链中的每个元素,但不能假设该列表保持静态 - 我必须在组件的每个adoptedconnected事件上重新附加观察者。

一个可能的解决方案是,当元素添加到页面时,它会递归搜索具有lang属性的第一个父/祖先,向其添加MutationObserver并响应对该特定父元素的更改。

IMO试图为所有父母观察变化是一个低效的设计选择,听起来也像是一个矫枉过正的功能。

我没有亲自尝试过,但要检测浏览器语言的变化,请查看languagechange事件。

最新更新