在使用带有Google chome和开发人员工具的网络组件时使用添加样式表时出现问题

问题描述

我在将WebComponent实例的过继样式表添加到文档中时遇到问题。

我的自定义Web组件在构造函数中创建了一个新的CSsstyleSheet实例。当组件通过connectedCallback升级时,它将实例添加到document.adoptedStyleSheets中。 然后,我有一个update()-Method,以后可以调用它来更改所采用样式表的css属性

在以下示例中,您可以查看用法。我的HTML包含两个自定义组件以及一些用于添加删除样式属性的按钮。

我们可以通过使用添加按钮向两个组件添加不同的样式。在未打开开发人员属性之前,一切工作正常。 如果打开开发人员属性并重新加载该示例,则似乎添加到采用的StyleSheets中的两个CSsstyleSheet实例都引用同一实例。

单击元素1旁边的“应用样式”按钮将为元素1添加绿色边框。

单击元素2旁边的“应用样式”按钮,将在元素2上添加黑色边框。

但是它删除了Element 1的样式。这不会发生,因为Element 1的CSsstyleSheet对象仍然应该具有css属性。但是他们迷路了。

class CustomElem extends HTMLElement {
  
  constructor() {
    super();
    this.myStyle = new CSsstyleSheet();
  }

  connectedCallback() {
    document.adoptedStyleSheets = [ ...document.adoptedStyleSheets,this.myStyle ];
  }
  
  update(css) {
    this.myStyle.replaceSync(css);
  }
}

customElements.define('custom-elem',CustomElem);

document.getElementById('btn1_add').addEventListener('click',function() {
  document.getElementById('elem1').update('custom-elem#elem1 { border: 3px solid green; }');
});

document.getElementById('btn2_add').addEventListener('click',function() {
  document.getElementById('elem2').update('custom-elem#elem2 { border: 3px solid black; }')
});

document.getElementById('btn1_remove').addEventListener('click',function() {
  document.getElementById('elem1').update('');
});

document.getElementById('btn2_remove').addEventListener('click',function() {
  document.getElementById('elem2').update('')
});
<html>
  <head></head>
  <body>
    Custom Elements<br /><br/>
    <custom-elem id="elem1">Element 1</custom-elem>
    <input type="button" id="btn1_add" value="Apply Style"></input>
    <input type="button" id="btn1_remove" value="Remove Style"></input>
    <br /><br />
    <custom-elem id="elem2">Element 2</custom-elem>
    <input type="button" id="btn2_add" value="Apply Style"></input>
    <input type="button" id="btn2_remove" value="Remove Style"></input>   
  </body>
</html>

我的第二个示例解决了此问题。如果我直接在connectedCallback中调用replaceSync(''),那么一切都会按预期进行。

class CustomElem extends HTMLElement {
  
  constructor() {
    super();
    this.myStyle = new CSsstyleSheet();
  }

  connectedCallback() {
    document.adoptedStyleSheets = [ ...document.adoptedStyleSheets,this.myStyle ];    
    // *****************************
    // this makes it work!
    // *****************************
    this.myStyle.replaceSync('');
  }
  
  update(css) {
    this.myStyle.replaceSync(css);
  }
}

customElements.define('custom-elem',function() {
  document.getElementById('elem2').update('')
});
<html>
  <head></head>
  <body>
    Custom Elements<br /><br/>
    <custom-elem id="elem1">Element 1</custom-elem>
    <input type="button" id="btn1_add" value="Apply Style"></input>
    <input type="button" id="btn1_remove" value="Remove Style"></input>
    <br /><br />
    <custom-elem id="elem2">Element 2</custom-elem>
    <input type="button" id="btn2_add" value="Apply Style"></input>
    <input type="button" id="btn2_remove" value="Remove Style"></input>
  </body>
</html>

有人可以告诉我,为什么会这样吗?

解决方法

根据issue you've reported on bugs.chromium.org,这实际上是Chrome回归,引入了与Chrome 85中的样式表突变相关的更改。它在85年前已经正常工作。

顺便说一句,非常好的复制者!

fix has already been implemented和可以使用Chrome Canary进行验证。该修补程序将在Chrome 88中登陆,该Chrome 88将于2021年1月19日成为稳定版本(请参见releases)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...