【问题标题】:Observing Constructible StyleSheets changes观察可构造样式表的变化
【发布时间】:2021-06-07 02:25:59
【问题描述】:

我有以下使用可构造样式表的代码 sn-p。 (当点击按钮时,附加的可构造样式表会更新为随机颜色)。

我如何观察和聆听这种变化? (我想捕获元素上计算的样式更改,或者 - 更新的可构造样式表)

var div1 = document.getElementById("div1");


var observer = new MutationObserver(function (mutations) {
  let text = "";
  mutations.forEach(function (mutation) {
    text += "changed " + mutation.attributeName;
  });
  document.getElementById("output").innerHTML += `<div>${text}</div>`;
});

var observerConfig = {
  attributes: true
};

var targetNode = document.getElementById("div1");

document.getElementById("btnAttachStyleSheet").addEventListener("click", () => {
  switch (Math.floor(Math.random() * 5)) {
    case 1:
      sheet.replaceSync(".color {color:blue}");
      break;
    case 2:
      sheet.replaceSync(".color {color:yellow}");
      break;
    case 3:
      sheet.replaceSync(".color {color:green}");
      break;
    case 4:
      sheet.replaceSync(".color {color:brown}");
      break;
    default:
      sheet.replaceSync(".color {color:pink}");
  }
});
const sheet = new CSSStyleSheet();
document.adoptedStyleSheets = [sheet];
observer.observe(targetNode, observerConfig);
<h1>Adopted stylesheets</h1>
<button id="btnAttachStyleSheet">Update style sheet</button>
<div style="padding: 1rem;" id="div1" class="color">colored div</div>

<h3>mutations:</h3>
<div id="output"></div>

【问题讨论】:

  • 我只是尝试在 Firefox 78.4.1 esr 上运行它,但它没有运行。经过一番研究,我发现可构造样式表仅在 Chomre 版本 73 及以后的版本中受支持。其他浏览器尚未实现此规范。以下是浏览器支持的详细信息:chromestatus.com/feature/5394843094220800。我之所以提到这一点,是因为如果对此没有广泛的支持,您可以考虑其他替代方案。

标签: javascript mutation-observers


【解决方案1】:

replaceSync 的规范没有提到触发任何事件。这不是 DOM 突变,因此您无法使用 `MutationObserver 观察它。

相反,如果您控制调用replaceSync 的代码,请调用您自己的函数来执行replaceSync,然后引发特定于您的代码的事件(replace 也是如此):

var div1 = document.getElementById("div1");

var targetNode = document.getElementById("div1");

document.getElementById("btnAttachStyleSheet").addEventListener("click", () => {
  switch (Math.floor(Math.random() * 5)) {
    case 1:
      sheetReplaceSync(sheet, ".color {color:blue}");
      break;
    case 2:
      sheetReplaceSync(sheet, ".color {color:yellow}");
      break;
    case 3:
      sheetReplaceSync(sheet, ".color {color:green}");
      break;
    case 4:
      sheetReplaceSync(sheet, ".color {color:brown}");
      break;
    default:
      sheetReplaceSync(sheet, ".color {color:pink}");
  }
});
const sheet = new CSSStyleSheet();
function sheetReplaceSync(sheet, ...args) {
    const result = sheet.replaceSync(...args);
    console.log("Changed!");
    return result;
}
function sheetReplace(sheet, ...args) {
    return sheet.replace(...args).then(result => {
        console.log("Changed!");
        return result;
    });
};
document.adoptedStyleSheets = [sheet];
<h1>Adopted stylesheets</h1>
<button id="btnAttachStyleSheet">Update style sheet</button>
<div style="padding: 1rem;" id="div1" class="color">colored div</div>
<h3>mutations:</h3>
<div id="output"></div>

如果您不控制调用replaceSync 的代码,您可以替换工作表上的方法(和replace)以利用它,但如果可能的话我会避免这样做:

var div1 = document.getElementById("div1");

var targetNode = document.getElementById("div1");

document.getElementById("btnAttachStyleSheet").addEventListener("click", () => {
  switch (Math.floor(Math.random() * 5)) {
    case 1:
      sheet.replaceSync(".color {color:blue}");
      break;
    case 2:
      sheet.replaceSync(".color {color:yellow}");
      break;
    case 3:
      sheet.replaceSync(".color {color:green}");
      break;
    case 4:
      sheet.replaceSync(".color {color:brown}");
      break;
    default:
      sheet.replaceSync(".color {color:pink}");
  }
});
const sheet = new CSSStyleSheet();
const replaceSync = sheet.replaceSync;
const replace = sheet.replace;
sheet.replaceSync = function(...args) {
    const result = replaceSync.call(this, ...args);
    console.log("Changed!");
    return result;
};
sheet.replace = function(...args) {
    return replace.call(this, ...args).then(result => {
        console.log("Changed!");
        return result;
    });
};
document.adoptedStyleSheets = [sheet];
<h1>Adopted stylesheets</h1>
<button id="btnAttachStyleSheet">Update style sheet</button>
<div style="padding: 1rem;" id="div1" class="color">colored div</div>
<h3>mutations:</h3>
<div id="output"></div>

【讨论】:

    猜你喜欢
    • 2020-10-19
    • 2021-11-06
    • 2015-06-01
    • 2017-09-07
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 2015-07-16
    • 2012-08-05
    相关资源
    最近更新 更多