以下是 Brian Kardell 的客座文章。几周前,我在链接到 Hitch.js 后,Brian 联系了我,提供了更多见解。这很有趣,所以我认为我们应该在这里分享。Hitch 是更大“可扩展 Web”运动的产物,其中包括一份 宣言、一个 社区小组 和一个 有趣的词语。
Hitch.js 到底是什么?
Hitch 是一个“prollyfill 引擎”(我们稍后会定义)的概念验证,专门用于 CSS 选择器。它允许您直接在 CSS 中使用 jQuery 风格的选择器插件。它基于 CSS 工作组几年前列出的提案,由 Yehuda Katz、我自己和一些其他人提出,以及与 Google 的 Tab Atkins 和 Mozilla 的 Boris Zbarsky 进行的非常长的电子邮件交流。在讨论过程中,我发现自己想证明一些东西,所以我会写一些代码。最后,我和我的朋友 Clint Hill 合作,将它串联起来并重新设计成一个可用的开源项目,以便为开发人员提供一些即时价值。这就是 Hitch.js。
它做到了吗?
我认为是的。它做了一些事情:首先,它阐明了 Alex Russell 和 Yehuda Katz 在技术架构组中讨论的另一个例子,即需要分层设计事物,以及对于许多事物,开发人员最终会重新实现浏览器已经做得更好的事情,因为我们被隔离在高级别,无法调整单个部分。在 CSS 中,我们缺少一些基本元素和良好的扩展点。添加这种东西令人惊讶地困难。它还有助于说服 CSS 工作组的某些关键成员,CSS 需要一些这样的东西。Tab 在他的博客上 写了关于它,在新年决心文章中。我非常有信心,我们将在未来几年内获得一些强大的新 CSS 功能。在此之前,我们有 Hitch。
你真的会用它来做什么?
这是关键问题,无论它是通过 Hitch 还是原生提供,您能用这种新发现的力量做什么?我认为您可以帮助永远改变 Web。我知道这听起来很宏大,但我认为确实如此。我们可以用它来帮助改进我们思考标准的整个模型。考虑一下:CSS 2 于 1998 年 5 月成为 W3C 推荐标准。我们可能仍然认为“CSS 3”是相对较新的东西——但实际上他们在 1999 年 8 月发布了 CSS 3 的第一个草案。早在那个时候,他们就讨论了比今天 CSS 选择器级别 3 中更多的选择器功能。想想看。如果您在他们开始 CSS 3 时还是个幼儿,那么现在您应该已经高中毕业了。有很多原因导致这种情况,但即使这被人为地延长了 5 倍,也意味着您必须等待几年才能让某些东西通过流程,直到任何人都真正可以使用它。然后它有时仅存在于 nightly 版本中,或者位于某个标志后面,因此您无法真正将其用于任何“真实”的东西。从历史上看,它会以前缀的形式添加,一些勇敢的人可能会开始使用它,但这很难,因为它仅在少数浏览器中有效。这意味着实际上还需要几年时间才能让足够广泛的受众使用它,然后发现,“我其实并不在乎其中一半的选择器,为什么他们不选择 X 呢?” 这种情况因以下事实而加剧:一旦达到这个阶段,您就真的很难说服任何人更改它,因为这意味着可能“破坏 Web”,就像他们喜欢说的那样。总之,这很糟糕。
它将如何帮助改变这种情况?这与可扩展 Web 有关吗?
如果,不是使用那种模型,而是允许您使用 CSS 选择器级别 4 或 5——或者现在任何提议的选择器——以一种性能合理的方式,并且您可以知道实现不会在您不知情的情况下发生变化?这应该是可能的,对吧?如果我们使用 _polyfill_ 来“填补空白”,为功能最弱的旧版浏览器提供合理的标准实现,那么为什么不首先构建合理的_提案_实现,这些实现可以在现代浏览器上运行——**prollyfill**——以便我们可以评估、迭代和竞争。如果我们这样做,我们就可以直奔主题,对吧?您现在可以在它们进一步发展之前抱怨它们不好。如果我们在 GitHub 上公开这样做,您甚至可以 fork 它们并使其变得更好——而且您很可能会这样做,因为,面对现实:使用 GitHub 的人比参与 Web 标准讨论的人多得多。我们甚至可以收集有关使用情况、投诉、稳定性和供应商审查的数据,以确定何时某个功能“完善”到足以考虑迁移到原生实现并快速对其进行优先级排序。
你能举些例子吗?
假设选择器级别 4 提案中有一些您认为可能有用的东西,例如 :local-link 伪类,它允许您选择位于您域中以及不同 URL 级别(如导航链接中经常出现的那样)的链接。是它吗?您确定自己理解它吗?使用 Hitch,我们可以为此开发一个 prollyfill 并共享它——事实上,我们已经做到了——您可以查看它的演示。这意味着您实际上可以将其用于今天的一些实际用途。您也可以帮助改进它,在 GitHub 上 fork 它 并改进它,您可以向我发送拉取请求、分享您的用例、打开问题或添加一些 reftests。我们会将您发送的任何反馈信息关联到 CSS 工作组。
这是一个更简单的例子。我们将创建一个仅选择_外部_链接的选择器。首先链接 Hitch.js
<script src="http://hitchjs.com/dist/hitch-0.6.3.js"></script>
然后使用 Hitch 语法添加新的选择器。我们将确保 href 的主机名与窗口的主机名匹配。
Hitch.add([{
type: 'selector',
name: '-links-external',
base: '[href]',
filter: function (match, argsString, o) {
if (!match.hostname) {
return false;
}
return match.hostname !== window.location.hostname;
}
}]);
然后我们可以在 CSS 中使用我们设置的name
。请注意 CSS 上的特殊属性,它确保 Hitch 对其进行解析。
<style data-hitch-interpret>
a:-links-external() {
background-color: yellow;
}
</style>
Check out this Pen!
或者,假设您有一个尚未在任何草案中的选择器提案:您可以编写一个 prollyfill 并通过创建类似于上面提到的 git 来提交草案,并与 CSS 工作组共享。事实上,这种情况已经发生,您可以在我们的文章关于 :time – 驯服标准流程 中阅读到它。更好的是,如果浏览器供应商尽可能地遵循相同的模式呢?好吧,这种情况也发生了:Adobe 对区域提案做了类似的事情——他们没有使用 Hitch,因为他们不知道它,但他们编写了一种类似的单次使用代码。Mozilla 使用 X-Tags 做了这件事,Google 使用 Polymer 做了这件事——两者都可以更自由地发展、在任何现代浏览器中使用,甚至可以在我们匆忙提交之前在浏览器之外进行一些竞争。我们对 Futures/Promises 和 Navigation Controller 也遵循了同样的基本理念。我认为这些都是巨大的成功,它们帮助我们协调了许多团队,并以新的方式汇集了许多思想。
Hitch 与 Web Components 的关系如何?
它包含了一些关于 Web Components 的内容,但那些内容基于早期的草案。它早于 Mozilla 的 X-Tags 或 Google 的 Polymer,我们没有真正兴趣与它们竞争。事实上,我们很乐意合作。这两者都更好,并且基于更新的工作。只是碰巧我们在内部做了 95% 的必要工作,以便轻松地让一个简单的元素“升级”,所以我们将其公开。如果你只是想分解成模块化的“小部件”,你可能可以不用更多的东西就搞定。但这不是它的重点。
你提到 Hitch 不是一个预处理器,为什么不是呢?
就目前而言,Hitch 包含了 CSS 预处理器的某些方面,但它不是一个预处理器。它并非旨在替代 Sass 等工具,只是碰巧在内部公开一些简单的预处理很容易,所以我们就公开了。如果你只需要一些简单的标记替换,你可能可以不用更多的东西就搞定,但这不是它的重点。事实上,Hitch 中实际“引擎”的输入甚至不是 CSS,而是一种解析树。它是分层的,这样如果我们能与 Sass 等现有工具合作,我们就可以将预处理部分移出。我们现在将其保持简单,因为有些人没有强大的预处理器,也不想要,而且我们真的不想尝试与他们竞争。对于我们来说,在优化方面与他们合作更好。
所有这些与可扩展 Web 有什么关系?
这就是 可扩展 Web 宣言 的核心——改变我们思考标准的方式。Hitch 比这更早,所以我不能诚实地说它是所有这些的“完美”例子。我们中的几个人在同一时间得出了非常相似的结论,我们已经讨论了很长时间,并且一直在完善它。但它至少在较高层次上说明了我们希望如何改变模型,并使优秀的开发者能够帮助 #extendthewebforward。如果这一切对你来说听起来很有吸引力,我鼓励你去阅读它。并希望你也能签署它。然后告诉你的朋友!
好的。我在传播这个。太酷了。
很棒的东西!性能如何?
“类似 Hitch”的 CSS Regions polyfill 可以在这里找到: https://github.com/adobe-webplatform/css-regions-polyfill
让我想起了 angular.js 中的 指令,在更轻量级的独立版本中拥有它真是太棒了。
确实是一篇有趣的文章,但无法弄清楚在我们的 Web 项目中如何使用它。
在 hitchjs 官方网站上有一个很好的介绍视频。简而言之,你可以使用例如像 .a < .b 这样的父选择器,以及社区创建的许多其他选择器。或者你可以通过编写自己的选择器来公开 CSS 选择器集。无需等待它们在 CSS4 中实现。
有提到性能吗?
非常希望最终能够使用 CSS 父选择器,但我在他们的文档或代码库中没有看到示例(我是不是眼瞎了?)。
我经常发现自己想要在某个子元素的属性更改时为父元素设置样式。
一些即将发布的信息: http://www.youtube.com/watch?feature=player_detailpage&v=KTDsCB7ujXU#t=919s
你可以使用 :-hitch-has() - 它就像 jQuery :has() 一样工作,并且是最初提出的你所描述内容的方案。
http://hitchjs.wordpress.com/2012/05/09/content-based-css-hitch-has/ 相关细节
谢谢 Brian,这正是我要找的!
太棒了!明天要好好试试。
所以它是一个构建我们自己的 polyfill 的框架?
听起来棒极了!
需要注意的一点是,这是一个 JavaScript CSS 解释器,这意味着页面加载后对伪元素的更改不会反映出来,除非你连接额外的 JavaScript 来在所述伪元素更改时调用 hitch。让我解释一下……
我希望能够在子伪元素更改时更改父元素的 CSS。
<style data-hitch-interpret>
p:-hitch-has(input:checked) {
color:red;
}
</style>
<p>
父元素 1 文本
<input type="checkbox" checked>
</p>
<p>
父元素 2 文本
<input type="checkbox">
</p>
<script type="text/javascript" src="http://www.hitchjs.com/dist/hitch-0.6.1.min.js"></script>
在上面的示例中,“-hitch-has”选择器在初始页面加载时效果很好(第一个复选框的默认状态为“选中”,其父元素“p”颜色为“红色”)。当你在页面加载后与伪元素交互(选中/取消选中复选框)时,问题就出现了。
无论如何,我只是想分享一下我目前的经验……