【发布时间】:2020-05-29 14:17:26
【问题描述】:
我正在尝试编写可识别语言环境的 custom element。为了格式化它的输出,它在自身及其父元素上查找 lang 属性,然后返回浏览器 navigator.language UI 本地化。
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 似乎是一个尴尬的选择:我必须将它附加到父链中的 每个 元素,但不能假设该列表保持静态 - 我必须在组件的每个adopted 或connected 事件上重新附加观察者。
【问题讨论】:
-
A MutationObserver 是观察元素 Y 上属性 X 变化的唯一合理方法。请注意,您不必必须在每个元素上设置 MO,您可以添加
document级别的 MO -
这并不能解决尴尬。1。根级别的 MO 将报告属性更改on all elements,即使它们不在父链中。 2. 如果该组件在一个网站中被重复使用十次,最终会在同一个元素上出现十个 MO,观察相同的属性 - 或者,在组件之间共享它时,会破坏组件的原子性。
-
1.正确(我通常通过在控制台中输入
.1+.2来结束任何尴尬的辩论,以解释 Web 世界并不完美) 2. 在添加了你的 MO 的body标记上添加标记/属性. -
1.当然,shadowDOM 内部的突变不会被捕获:stackoverflow.com/questions/46995421/…
标签: javascript html dom localization web-component