javascript - 覆盖 element.styleSheet.cssText

标签 javascript

我正在寻找重写 element.styleSheet.cssText 函数

element = document.createElement("style");
element.styleSheet.cssText = ...

Object.prototype.styleSheet.cssText = function(){
    console.log('override');
}

我收到一条错误,指出 styleSheet 为 null 或未定义。我正在使用 Internet Explorer,所以我期望 stylesheet 存在。

感谢任何帮助

最佳答案

据我所知,没有真正的方法来覆盖 CSSStyleDeclaration 上的 native cssText 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 属性实现了当我们尝试获取/设置 cssText 属性时调用的 native getter/setter。

好吧,好吧!让我们重新定义自定义 CSSStyleDeclaration.prototype.cssText getter/setter。好吧,这不起作用,因为 cssText 属性似乎不是来自原型(prototype),即使它会 there's no way to get custom getters/setters使用Object.getOwnPropertyDescriptor因此我们将无法从自定义函数中调用 native setter。

我们还是来看看吧:

Object.defineProperty(CSSStyleDeclaration.prototype, 'cssText', {
    get: function () { return 'overrided'; }
});

document.createElement('style').style.cssText; //(empty string)

那有办法解决吗?好吧,可能还没有安全的解决方案来做到这一点,但最好的选择是用新创建的元素上的自定义访问器替换 style 属性。该访问器将返回一个对象,该对象实现与 CSSStyleDeclaration 实例相同的接口(interface),但所有访问器/函数都将被替换,以将操作委托(delegate)给原始样式对象。

返回的对象基本上充当真实样式对象的代理对象。这将是唯一的方法,因为我们无法访问 native getter/setter 函数,否则我们可以仅在元素的 native 样式对象上重新定义 cssText 访问器。

在下面的示例中,我仅通过代理 cssText 属性来演示这个想法。

注意:我们创建 CSSStyleDeclaration.prototype 实例的原因是确保 styleProxy instanceof CSSStyleDeclaration 保持 true。

实现不完整且使用不安全

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;

关于javascript - 覆盖 element.styleSheet.cssText,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19775573/

相关文章:

javascript - 当提示 "Did you find anything..."运行时,提示文本包含 "false"而不是实际文本

javascript - 执行 jQuery Promise

javascript - https可调用云函数不返回值

php - 包括 file.php + id。这可以用 php 实现吗?

javascript - $.on() 在 stopPropagation() 之后冒泡;

javascript - SetInterval定时改变单元格颜色

javascript - 使用 Shopify API 请求在自定义网站上使用 JavaScript 获取所有产品

javascript - Vanilla Javascript for 循环从选定集合中删除 html 元素

javascript - 如何使用 setInterval 函数显示屏幕上出现的每个值之间间隔 500 毫秒的阶乘计算?

javascript - 在 javascript 中从类似 "20161126 00:00"的字符串创建日期