{x:expression(...)} 是做什么的?

What does {x:expression(...)} do?

我遇到了这个 querySelectorAll for IE7 的 polyfill:

https://gist.github.com/connrs/2724353

我还以为我是JavaScript中的Okayish,但我从来没有看到像polyfill第9行中引用的部分:

{x:expression(document.__qsaels.push(this))}

显然,它是一个 JavaScript 对象,具有键 x 和值 expression(document.__qsaels.push(this)),但除此之外,我知道它对我来说很神秘。这个 expression 函数有什么作用?我无法通过 google.

找到任何接近的东西

您正在查看生成的 CSS 规则。这不是 JavaScript 对象,而是 CSS 声明块。

styleTag.styleSheet.cssText = selector + "{x:expression(document.__qsaels.push(this))}";

将带有声明块的 CSS 选择器连接成 CSS 的字符串。声明块包含一个名为 x 的虚拟 CSS 属性,其值为 expression(document.__qsaels.push(this)).

什么expression(),是老版本IE的一个非标准特性,允许作者直接执行任意JavaScript,得到一个在 CSS 内使用的值。因此,虽然整个字符串是一个 CSS 声明块,但 document.__qsaels.push(this) 实际上是一个 JavaScript 表达式。

这个表达式的作用是将匹配 CSS 选择器的任何元素推入 __qsaels 数组,以便 polyfill 可以 return 它作为选择器匹配的元素集.1 本质上,这就是 polyfill 的工作方式。

作为具体示例,调用 polyfilled document.querySelectorAll(".foo") 会导致 IE7 将以下 CSS 附加到文档样式表:

.foo{x:expression(document.__qsaels.push(this))}

有一些缩进和换行符,所以它类似于常规 CSS:

.foo {
  x: expression(document.__qsaels.push(this))
}

在这里你可以看到这个 CSS 规则将应用于匹配 .foo 的任何元素,导致每个元素在 return 之前被添加到 __qsaels编辑


1 无论出于何种原因,IE 似乎很乐意执行 expression() 语句,即使是在未知属性上(据我所知,没有这样的 属性 甚至在 IE7 上调用 x,但我知道什么?)。