简体   繁体   English

CSSStyleSheet object 无法克隆

[英]CSSStyleSheet object can't be cloned

I would like to use a CSSStyleSheet object in a redux store.我想在 redux 商店中使用CSSStyleSheet object。 However when I try to clone this kind of object I get an empty object.但是,当我尝试克隆这种 object 时,我得到一个空的 object。

 const styleContainer = document.createElement('style') styleContainer.innerHTML = 'p{color:green}'; document.head.appendChild(styleContainer); const sheet = styleContainer.sheet console.log(sheet); // [Object] console.log({...sheet }); // {} console.log(Object.assign({}, sheet)); // {} console.log(JSON.parse(JSON.stringify(sheet))); // {}

When you type the following statement:当您键入以下语句时:

{ ...sheet }

it's probably translated into:它可能被翻译成:

Object.assign({}, sheet);

or in essence Object.assign() can be rewritten as:或者本质上Object.assign()可以重写为:

var newObject = {};

Object.keys(sheet).forEach((key) => {
  newObject[key] = sheet[key];
});

Which copies all enumerable properties to the newly created Object .它将所有可枚举属性复制到新创建的Object prototype will not be copied either so even if the object solely relies on enumerable properties to function, it won't be the same object, neither a copy of it. prototype也不会被复制,因此即使 object 仅依赖于 function 的可枚举属性,它也不会是相同的 object,也不是它的副本。

Also note that spread is a shallow copy, it's merely copying primitive types and references to objects and you can verify that empirically:另请注意,spread 是浅拷贝,它只是复制原始类型和对对象的引用,您可以凭经验验证:

var b = { x: true }; 
var a = { b: b };

a.b == b // true
a.b == { x: true } // false

Back to CSSStyleSheet .回到CSSStyleSheet All native classes visible in JavaScript are backed by native classes implemented in C/C++. JavaScript 中可见的所有本机类均由以 C/C++ 实现的本机类提供支持。 You can confirm that empirically:您可以凭经验确认:

var s = new CSSStyleSheet()


s.addRule.toString()
// "function addRule() {
//    [native code]
//"

s.prototype
// undefined 

Note that functions on such objects say [native code] and there is no prototype.请注意,此类对象上的函数表示[native code]并且没有原型。

When you spread such object, that connection with native class becomes severed and a generic Object is produced instead.当您传播此类 object 时,与本机 class 的连接将被切断,而是生成通用Object

I would suggest to serialize the object yourself and then re-create it when you need it.我建议自己序列化 object,然后在需要时重新创建它。

For example you could serialize CSS rules and store them in Redux:例如,您可以序列化 CSS 规则并将它们存储在 Redux 中:

var stylesheet = new CSSStyleSheet();
stylesheet.replaceSync('p { color: green; }');

var payload = "";
var rules = stylesheet.cssRules;
for (var i = 0; i < rules.length; i++) {
  payload += rules[i].cssText + "\n";
}

reduxStore.dispatch({ type: 'STORE_CSS', payload: payload });

Then when you need to manipulate the CSS stylesheet, you could re-create the CSSStyleSheet object and feed it with CSS rules:然后,当您需要操作 CSS 样式表时,您可以重新创建CSSStyleSheet object 并使用 CSS 规则对其进行输入:

var stylesheet = new CSSStyleSheet();
stylesheet.replaceSync(payloadFromReduxStore);

Note that at the time of writing this, Safari does not support the programmatic instantiation of CSSStyleSheet objects but Firefox does.请注意,在撰写本文时,Safari 不支持CSSStyleSheet对象的编程实例化,但 Firefox 支持。

So perhaps going via style tag would be necessary to workaround that, ie in some browsers:因此,也许需要通过style标签来解决这个问题,即在某些浏览器中:

vary styleContainer = document.createElement('style');
styleContainer.innerHTML = 'p { color:green }';
document.head.appendChild(styleContainer);

var stylesheet.replaceSync = styleContainer.sheet

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM