我想覆盖element.styleSheet.cssText
功能
element = document.createElement("style");
element.styleSheet.cssText = ...
Object.prototype.styleSheet.cssText = function(){
console.log('override');
}
我收到样式表为null或未定义的错误。我正在使用Internet Explorer,所以我希望
stylesheet
存在。任何帮助表示赞赏
最佳答案
据我所知,没有真正的方法可以覆盖cssText
对象上的本机CSSStyleDeclaration
getter。
让我们看看为什么:
var s = document.createElement('style'),
style = s.style;
style instanceof CSSStyleDeclaration; //true
到目前为止,一切顺利,但是当我们尝试设置
cssText
属性时:style.cssText = 'something';
style.cssText; //(empty string), the native setter did not allow setting an invalid style
如我们所见,
cssText
属性实现了本机的getter / setter,它们在我们尝试获取/设置cssText
属性时被调用。好的!让我们重新定义自定义
CSSStyleDeclaration.prototype.cssText
getter / setter。嗯,这是行不通的,因为似乎cssText
属性不是来自原型,即使它使用there's no way to get custom getters/setters Object.getOwnPropertyDescriptor
也是如此,因此我们将无法从自定义函数调用本机setter。无论如何,让我们看看:
Object.defineProperty(CSSStyleDeclaration.prototype, 'cssText', {
get: function () { return 'overrided'; }
});
document.createElement('style').style.cssText; //(empty string)
那有解决办法吗?好吧,可能还没有安全的解决方案,但是最好的选择是用新创建的元素上的自定义访问器替换
style
属性。该访问器将返回一个实现与CSSStyleDeclaration
实例相同接口的对象,但是所有访问器/函数都将被替换以将操作委派给原始样式对象。返回的对象基本上将充当真实样式对象的代理对象。那是唯一的方法,因为我们无法访问本机的getters / setters函数,否则我们只能在元素的本机样式对象上重新定义
cssText
访问器。在下面的示例中,我仅通过代理
cssText
属性来演示该想法。注意:我们创建
CSSStyleDeclaration.prototype
实例的原因是为了确保styleProxy instanceof CSSStyleDeclaration
保持为真。该实现不完整且使用不安全
document.createElement = (function (doc, nativeCreateEl) {
return function() {
var el = nativeCreateEl.apply(doc, arguments),
nativeStyle = el.style,
styleProxy = Object.create(CSSStyleDeclaration.prototype);
Object.defineProperty(el, 'style', {
get: function () {
return styleProxy;
}
});
Object.defineProperty(styleProxy, 'cssText', {
set: function (styles) {
console.log('setting cssText');
nativeStyle.cssText = styles;
},
get: function () {
return nativeStyle.cssText;
}
});
return el;
};
})(document, document.createElement);
var el = document.createElement('div'),
s = el.style;
s.cssText = 'test'; //logs setting cssText
s.cssText; //(empty string) -> this is expected
s.cssText = 'color: red;'; //logs setting cssText
s.cssText; //color: red;