WebComponent可以代替你的前端框架吗?(2)

电脑杂谈  发布时间:2019-08-27 12:03:46  来源:网络整理

classMyElementextendsHTMLElement{

staticgetobservedAttributes(){

return['disabled'];

}

constructor(){

constshadowRoot=this.attachShadow({mode:'open'});

shadowRoot.innerHTML=`

<style>

.disabled{

opacity:0.4;

}

</style>

<divid="container"></div>

`;

this.container=this.shadowRoot('#container');

}

attributeChangedCallback(attr,oldVal,newVal){

if(attr==='disabled'){

if(this.disabled){

this.container.classList.add('disabled');

}

else{

this.container.classList.remove('disabled')

}

}

}

}

以后无论何时disabled的attribute被改变时,this.container上面的名为disabled的class都会显示或隐藏,它是ShadowDOM的内在元素。接下去让我们看一下。

ShadowDOM

使用ShadowDOM,自定义元素的HTML和CSS完全封装在模块内。这意味着元素将以单个的HTML标签出现在文档的DOM树种。其外部的构架将会放在#shadow-root。

实际上一些原生的HTML元素也使用了ShadowDOM。例如你再一个网页中有一个<video>元素,它将要成为一个单独的标签展现,但它也将显示播放和暂停视频的控件,当你在浏览器开发软件中查看video标签,是看不到这种控件。

这种控件实际上就是video元素的ShadowDOM的一个别,因此默认状况下是隐藏的。要在Chrome中显示ShadowDOM,进入开发者软件中的Preferences中,选中ShowuseragentShadowDOM。当你在开发者软件中重新查看video元素时,你就可以看见该元素的ShadowDOM了。

ShadowDOM还提供了局部作用域的CSS。所有的CSS都只应用于模块本身。元素将只继承最小数量从模块内部定义的CSS,甚至可以不从内部继承任何CSS。不过你可以暴露很多CSS属性,以便用户对模块进行样式修改。这可以缓解许多CSS问题,同时依然允许自定义模块样式。定义一个Shadowroot:

constshadowRoot=this.attachShadow({mode:'open'});

shadowRoot.innerHTML=`<p>Helloworld</p>`;

这定义了一个带mode:open的Shadowroot,这意味着可以再开发者工具找到它并与之交互,配置暴露出的CSS属性,抛出的事件。同样也可以定义mode:closed,会受到与之相反的体现。

你可以使用使用HTML字符串添加到innerHtml的property属性中,或者使用一个<template>去给Shadowroot添加HTML。一个HTML的template基本是惰性的HTML片段,你可以定义了提前使用。在实际插入DOM前,它是不可见也不可解读的。这意味着定义在外部的任何资源都能够获得,任何外部定义的CSS和Java只有当它被插入DOM中时,才会被执行。当模块的HTML根据其状况出现设置时,例如你可以定义多个<template>元素,然后按照模块的状况去插入某些元素,这样可以轻松的设置模块的HTML部分,并不应该设置单个DOM节点。

当Shadowroot被创建以后,你可以使用document对象的所有DOM方法,例如this.shadowRoot.querySelector去查找元素。组件的所有颜色都被定义在style标签内,如果你想使用一个常规的<link>标签,你也可以获得内部风格。除此之外,还可以使用:host选择器对模块本身进行风格设定。例如,自定义元素默认使用display:inline,所以即使你想要将模块展示为款元素,你可以这么做:

:host{

display:block;

}

这还允许你进行上下文的风格化。例如你想要借助disabled的attribute来改变组件的背景是否为红色:

:host([disabled]){

opacity:0.5;

}

webcomponents可以删除吗_webcomponents可以删除吗_win7c盘哪些文件可以删除

默认状况下,自定义元素从周围的CSS中继承一些属性,例如色彩和图标等,如果你想清空组件的初始状况以及将模块内的所有CSS都设定为默认的初始值,你可以使用:

:host{

all:initial;

}

特别重要,需要留意的一点是,从内部定义在模块本身的风格优先于使用:host在ShadowDOM中定义的风格。如果你这么做

my-element{

display:inline-block;

}

它将会被覆盖

:host{

display:block;

}

不需要从内部去颠覆自定义元素的风格。如果你期望客户可以修改模块的个别颜色,你可以暴露CSS变量去超过这个效果。例如你想让客户可以选用模块的背景色彩,可以暴露一个叫—background-color的CSS变量。假设今天有一个ShadowDOM的根节点是<div>

#container{

background-color:var(--background-color);

}

目前用户可以在模块的内部设定它的背景色彩

my-element{

--background-color:#ff0000;

}

你还可以在模块内修改一个默认值,以防用户没有修改

:host{

--background-color:#ffffff;

}

#container{

background-color:var(--background-color);

}

其实你还可以让客户设定任何的CSS变量,前提是这种变量的命名要以—开头。

通过提供局部的CSS、HTML,ShadowDOM解决了全部CSS可能带给的一些弊端,这样难题往往造成不断地添加颜色表,其中包括了愈发越多的选择器和覆盖。ShadowDOM似的标记和颜色捆绑到自己的模块内,而不应该任何工具和命名约定。你再也不用害怕新的class或id会与现有的任何一个冲突。

除此之外,还可以借助CSS变量设定web模块的外部形状,还可以将HTML注入到WebComponents中。

通过slots组成

组合是借助ShadowDOM树与用户提供的标记组合在一起的过程。这是借助<slot>元素完成的,该元素基本是ShadowDOM的占位符,用来呈现用户提供的标记。用户提供的标记又可以作为lightDOM。合成会将lightDOM和ShadowDOM合并作为一个新的DOM树。

比如,你可以创建一个<iamge-gallery>组件,并提供标准的img标签成为模块要展现的内容:

<image-gallery>

<imgsrc="foo.jpg"slot="image">

<imgsrc="bar.jpg"slot="image">

</image-gallery>

组件目前即将获得两个提供的图像,并且使用slots将他们渲染到模块的ShadowDOM中。注意到slot=”image”的attribute,这告诉了模块需要要在ShadowDOM的哪些位置渲染他们。例如这种

<divid="container">

<divclass="images">

<slotname="image"></slot>

</div>

</div>

当lightDOM中的节点被分发到ShadowDOM中时,得到的DOM树看上去是这么的:

<divid="container">

<divclass="images">

<slotname="image">

<imgsrc="foo.jpg"slot="image">

<imgsrc="bar.jpg"slot="image">

</slot>

</div>

</div>

就像你看见的,任何客户提供的具备slot属性的元素,都将在slot元素中展现。而slot元素具备name属性,其值与slot属性的值对应。<select>元素的工作方与此完全相似,你可以在开发这软件中查看(查看修改在上面)

它接受用户提供的option元素,并将他们展现到下拉菜单中。带有name属性的slot被称为具名slot,但是这个属性不是需要的。它仅用于必须将内容展现在特定位置时使用。当一个或多个slot没有name属性时,将根据用户提供内容的顺序在其中展现。当用户提供的内容超过slot时,slot可以提供默认的展示。

看一下<image-gallery>的ShadowDOM:

<divid="container">

<divclass="images">

<slot></slot>

<slot></slot>

<slot>

<strong>Noimagehere!</strong><--fallbackcontent-->

</slot>

</div>

</div>

即使你再只给两个image的话,最后的结果如下:

<divid="container">

<divclass="images">

<slot>

<imgsrc="foo.jpg">

</slot>

<slot>

<imgsrc="bar.jpg">

</slot>

<slot>

<strong>Noimagehere!</strong>

</slot>

win7c盘哪些文件可以删除_webcomponents可以删除吗_webcomponents可以删除吗

</div>

</div>

通过slot在ShadowDOM中展现的元素被称为分发节点。这些部件被插入前的形状也即将被用于人们插入后。在ShadowDOM中,分发节点可以借助::sloted()来获得额外的样式

::slotted(img){

float:left;

}

::sloted()可以接受任何有效的CSS选择器,但它没法选择老牌节点,例如::slotedd(sectionimg)的状况,将不会作用于thiscontent

<image-gallery>

<sectionslot="image">

<imgsrc="foo.jpg">

</section>

</image-gallery>在Java中使用slots

你可以借助Java与slots进行交互去检测哪个结点被分发到什么slot,哪些slot被插入了元素,以及slotchange事件。

要找出这些元素终于被分发给对应的slots可以使用slot.assignedNodes()假如你还想查看slot的默认内容,你可以使用slot.assignedNodes({flatten:true})要找出这些slot被分发的元素,可以使用element.assignedSlot当slot内的节点出现改变,即添加或删除节点时,将会出发slotchange事件。要切记的是,只有当slot节点自身改变才能触发webcomponents可以删除吗,而这种slot节点的子节点并不会触发。


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/sanxing/article-120724-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 石召
      石召

      人家做生意上来先给你个大金戒指

    热点图片
    拼命载入中...