ShadowDom - 封装私有样式
Angular2采用ShadowDom作为组件的渲染基础,这意味着组件被渲染到独立的Shadow Tree上,这很好,可以实现DOM对象和样式的良好封装:
但问题是,除了Chrome之外的大多数的浏览器目前还不支持ShadowDom,因此,Angular2 提供了三种将模板渲染到DOM的策略。
以下面的模板为例,我们看三种策略下的渲染结果差异:
1 @View{ 2 template:"<h1>hello</h1>", 3 styles:["h1{color:red}"] 4 }
全局仿真策略/EmulatedUnscopedShadowDomStrategy
采用这个策略时,Angular2将模板直接插入DOM树,并将模板的样式原封不动地插入head头部。这意味着 不同组件之间的样式可能冲突 : 在右边的示例代码中,你可以清楚的看到,EzApp组件的h1样式污染了其他的 h1元素,所有的h1都变成红色了。
示例代码渲染后的DOM如下:
这个策略不需要浏览器原生支持ShadowDom,是当前版本(alpha.28)的默认策略。
作用域仿真策略/EmulatedScopedShadowDomStrategy
采用这个策略时,Angular2将模板直接插入DOM树,对模板的样式重新定义CSS选择符后 插入head头部。由于样式进行了重命名,所以不同组件之间的样式不会冲突。
示例代码在这个策略下的渲染结果是:
这个策略也不需要浏览器原生支持ShadowDom。
原生策略/NativeShadowDomStrategy
采用这个策略时,Angular2将在组件的宿主DOM对象上建立一个ShadowDom树,这颗树与主DOM树是隔离的,所以,这是实现Web组件的理想方案:
如果浏览器原生支持ShadowDom,那么应当使用这个策略。
例如:
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>template - shadowdom strategy</title> 6 <script type="text/javascript" src="lib/[email protected]"></script> 7 <script type="text/javascript" src="lib/angular2.dev.js"></script> 8 <script type="text/javascript" src="lib/system.config.js"></script> 9 </head> 10 <body> 11 <h1>我是H1,我在组件外</h1> 12 <ez-app></ez-app> 13 14 <script type="module"> 15 import {bind,Component,View,bootstrap} from "angular2/angular2"; 16 17 @Component({selector:"ez-app"}) 18 @View({ 19 template:"<h2>我是H2,我在组件内</h2>", 20 styles:["h2{color:red}"] 21 }) 22 class EzApp{} 23 24 bootstrap(EzApp); 25 26 </script> 27 </body> 28 </html>
结果如下:
时间: 2024-11-01 08:44:49