gpt4 book ai didi

javascript - 使用 webcomponentsjs 在 safari 和 firefox 中应用所有 webcomponent 样式

转载 作者:行者123 更新时间:2023-12-01 17:41:38 25 4
gpt4 key购买 nike

我有两个自定义元素:

<name-card data-color="#000000"></name-card>
<name-card data-color="#80B88C"></name-card>

我会将他们的 data-color 应用于样式。从我之前问的问题,如何获取cssRules,我得到了答案并将其添加到attachedCallback()中进行动态更改。

但是,它只是在 chrome 上显示正确的颜色,其他浏览器将最后一种颜色 #80B88C 应用到两者。

我检查了 attachedCallback() 中的循环

for(i = 0; i < rules.length; i++){
if(rules[i].selectorText === '.base'){
rules[i].style.background = bgColor;
}
}

并且都更改了正确的颜色,但我仍然不知道为什么他们将最后一种颜色应用于 safari 和 firefox 上的两种元素样式。

最佳答案

这是因为polyfill无法实现完全的css隔离。

因此,您在 polyfilled Shadow DOM 中添加的 CSS 样式表实际上应用于整个文档。当同名规则被使用两次时,最后一个获胜。这就是您在 Safari 和 Firefox 中观察到这种行为的原因。

在您的案例中有一个解决此问题的方法,它处理 ::before::after伪元素:

当前解决方案

  • 生成更具体的 cssRule其中包括特定颜色:

attachedCallback() 里面功能:

sheet.insertRule( '[data-color=' + bgColor + '] .base::before { background: ' + bgColor + ' ; }', sheet.length )

future 的解决方案

当 CSS 3 规范为 attr()在每个属性上都将实现:

  • 将颜色传播到目标元素并使用 attr()应用正确颜色的 CSS 函数,由属性传递(在您的示例中为 data-color)。

这个解决方案的优点是它的工作方式与 polyfill 和 native 实现相同,并且具有无限数量或颜色。

attachedCallback()功能:

var targets = this.querySelectorAll( '.base' )
for ( var i = 0 ; i < targets.length ; i++ )
{
targets[i].dataset.color = bgColor
}

<style>元素:

.base::before {
background: attr( data-color )
}

var proto = Object.create( HTMLElement.prototype )
proto.createdCallback = function ()
{
this.createShadowRoot()
var tmpl = document.querySelector( 'template' )
this.shadowRoot.appendChild( tmpl.content.cloneNode( true ) )
}
proto.attachedCallback = function ()
{
//get custom color
var bgColor = this.dataset.color

//add it to the top-level inside Shadow DOM
this.shadowRoot.querySelector( 'section' ).dataset.color = bgColor

//change the stylesheet in the next microtask
var style = this.shadowRoot.querySelector( 'style' )
setTimeout( function ()
{
var sheet = style.sheet
sheet.insertRule( '[data-color=' + bgColor
+ '] .base::after { background: ' + bgColor + ' ; }'
, sheet.cssRules.length )
} )
}
document.registerElement( 'name-card', { prototype: proto } )
<name-card data-color="red"></name-card>
<name-card data-color="green"></name-card>
<template>
<style>
.base::after {
content: '-postfix' ;
}
</style>
<section>
<div>Custom Element</div>
<span class="base">Base element</span>
</section>
</template>

关于javascript - 使用 webcomponentsjs 在 safari 和 firefox 中应用所有 webcomponent 样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39782740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com