我试图基于浏览器初始化带有或不带有Shadow DOM的组件(因为IE不支持Shadow DOM)。
我检查它是否为IE11,并将IE的封装设置为Emulated
,对于其他浏览器,将封装设置为ShadowDom
。
const agent = window.navigator.userAgent;
const isIe11 = agent.indexOf('MSIE') === -1 && agent.indexOf('Trident') > 0;
@Component({
selector: 'my-web-component',
templateUrl: '...html',
styleUrls: ['...scss'],
encapsulation: isIe11 ? ViewEncapsulation.Emulated : ViewEncapsulation.ShadowDom
})
export class NavbarComponent implements OnInit { ... }
根据浏览器检查的返回值,isIe11
的值是正确的,但是封装总是以ViewEncapsulation.Emulated
结束。
我通过DOM检查器确认了这一点,因为在DOM中看不到#shadow-root
。相反,我看到_ngcontent-c0
确认封装已被仿真。
答案 0 :(得分:1)
这在您设想的方式中是不可能的,因为angular在AOT模式下编译您的代码,并且在编译步骤中显然不知道浏览器。
我只能想到一种实现此目标的方法。您必须两次编译同一应用程序。对于不兼容ShadowDom
的浏览器,一次,并且可能的话。
然后,根据浏览器的请求,在服务器上为您提供所需的服务。我想您还可以在index.html
内找到一种破解方法,该方法将根据当前浏览器加载正确的角度库。这将需要一些ng build
之后的脚本。
不过,您可以从环境文件中处理所需的封装,因此,如果对于兼容和不兼容的浏览器有两种不同的环境,则可以在环境中添加一个属性:
// non shadow dom compatible env
export const environment = {
// ...
defaultEncapsulation: ViewEncapsulation.Emulated
}
// shadow dom compatible env
export const environment = {
// ...
defaultEncapsulation: ViewEncapsulation.ShadowDom
}
如果您的生产版本具有这两个环境文件,则可以在bootstrapModule
中编辑main.ts
方法以读取值:
platformBrowserDynamic().bootstrapModule(AppModule, {
defaultEncapsulation: environment.defaultEncapsulation
});