【发布时间】:2021-01-27 14:36:50
【问题描述】:
这不是关于如何扩展 JS 原生的问题,我很清楚此类活动所涉及的“危险”。我只是想更深入地了解 JavaScript 的工作原理。为什么如果我写以下内容:
CSSStyleSheet.prototype.sayHi = function() {
console.log('CSSStyleSheet says hi!');
};
var test = new CSSStyleSheet;
test.sayHi(); // Console output: CSSStyleSheet says hi!
我从 sayHi 函数中得到了预期的输出。但是,如果我随后查询一个样式元素并生成一个 CSSStyleSheet 对象 通过 sheet 属性从中获取,未定义 sayHi 函数:
var styleElm = document.querySelector('style'),
sheet = styleElm.sheet;
console.log('sheet', sheet) // Console output: sheet CSSStyleSheet {ownerRule: null,...
sheet.sayHi(); // Console output: Uncaught TypeError: sheet.sayHi is not a function
这是什么原因?我需要做些什么才能使 sayHi 函数可用于通过 sheet 属性生成的 CSSStyleSheet 对象 - 甚至可能吗?
测试在 Chrome 中运行。
编辑:
我之所以对此进行研究,是因为在简化现有代码方面,我试图权衡我的选择。我制作了一个 API 来操作 iFrame 中加载的文档的内部样式。它按预期工作,但我想尽可能简化代码。它建立在 CSSOM API 之上,允许通过数字索引访问单个 CSS 样式规则。将数字索引作为访问 CSS 规则的唯一方法似乎非常初级,因为除非您知道索引指向的规则,否则您永远不会请求特定的索引。也就是说,您总是需要有关选择器文本的信息。但考虑到 CSS 的级联特性(您可以根据需要多次使用相同的选择器文本),这是在广泛的上下文中有意义的唯一方法。
但是,我的 API 使事情井井有条,因此每个选择器文本都是唯一的。因此,索引规则是有意义的,以便访问它们的主要方式是通过它们的选择器文本,而我的 API 就是这样做的。但是,当有多个规则在使用时,事情很快就会变得不那么优雅,即,如果您有许多包含自己的 CSS 规则索引的媒体查询规则。
所以我只是想知道我是否可以做任何事情来简化代码,我必须承认,如果不是因为在这个线程中说明了托管对象的问题,我可能会考虑扩展 CSSStyleSheet 对象。
还有其他方法,我可以考虑吗?
【问题讨论】:
-
您的代码应该可以使用 AFAICT。请检查并重新运行。
-
你确定是同一个上下文吗?
-
@raina77ow,根据上下文,您指的是范围吗?
-
不,同样的
window。 -
@raina77ow,我想你可能在这里查明了实际问题。实际上,查询的样式元素存在于 iframe 中,但发出查询的脚本位于父窗口中。所以,如果这是问题的关键,我想我应该从 iframe 文档中加载的脚本扩展 CSSStyleSheet。但这似乎也没有解决它?
标签: javascript prototypal-inheritance