首先需要说明的是,您应该尽量使样式和 JavaScript 分开。如果要使用 JavaScript 更改元素的样式,请向元素添加(或删除)一个类名。然后在 CSS 中使用该类名作为挂钩来影响样式。
但是,有时您需要在 JavaScript 中应用样式。jQuery 恰好有一个函数可以做到这一点。
$("#thing").css("margin-right", 0);
它甚至可能有点吸引人,因为 jQuery 会为您处理一些跨浏览器问题。例如,不透明度就是那些需要 各种 CSS 属性 才能实现跨浏览器兼容性的属性之一。但是使用 jQuery,您无需应用所有这些属性。只需使用 CSS 函数设置不透明度即可。jQuery 知道它所在的浏览器环境,并将应用正确的属性。
// just works
// also alternate CSS syntax
$("#thing").css({
opacity: 0.5
});
因此,您可能会将这种思路扩展到假设 jQuery 会帮助您解决其他需要多个 CSS 属性才能获得相同跨浏览器效果的问题,例如典型的 border-radius 示例。我们需要-moz-border-radius用于 Mozilla 浏览器,-webkit-border-radius 用于 WebKit 浏览器,以及border-radius用于 Opera(以及未来)。但 jQuery 在这里帮不上忙。
// not gonna help in current Firefox or Safari/Chrome
$("#thing").css({
"border-radius": "20px"
});
要通过 jQuery 获得跨浏览器兼容的 CSS,我们仍然需要列出所有三个属性。
$("#thing").css({
"border-radius": "20px",
"-moz-border-radius": "20px",
"-webkit-border-radius": "20px"
});
这是怎么回事?David Walsh 认为 在 jQuery 中包含此抽象会增加库的体积。 Ben Alman 认为 jQuery 应该处理完全支持的 CSS 属性(border-radius 规范尚未正式确定)。Screwlewse 认为 唯一支持不透明度的方式是因为动画需要它(像 fadeToggle 这样的核心函数)。
我不确定我的想法是否完全正确。一方面,如果这些问题能够自动处理,那确实会很不错。另一方面,我理解库体积过大和规范尚未最终确定这两个论点。
您怎么看?
如果您发现自己需要通过 jQuery 应用圆角,那么您可能需要将其抽象到您自己的一个小插件中。
$.fn.roundThis = function(radius) {
return this.each(function(e) {
$(this).css({
"border-radius": radius,
"-moz-border-radius": radius,
"-webkit-border-radius": radius
});
});
};
$(function() {
// usage
$("#thing-that-will-become-rounded").roundThis("20px");
});
但这仍然无法处理 IE,但有一些 很棒的插件可以做到。
其他新闻:恭喜 Brent Traut 赢得了我的小型竞赛中免费的 jQuery 大会 门票。有 10 人参加了竞赛,他们总共向开源项目捐赠了 115 美元。伪随机数生成 选出了获胜者。如果您还在考虑参加,那么您应该去!如果您还在考虑向开源项目捐款,那么您也应该这样做!
正如您所说,如果 jQuery 能解决这个问题,那将是很棒的,但我认为我会同意 Ben Alman 的想法:“jQuery 应该处理完全支持的 CSS”。
我同意 jQuery 应该将额外的非标准内容排除在库之外的想法。尤其是在我认为我们很快就会看到像圆角这样的 CSS3 工具在所有浏览器中都得到支持,而无需使用专有的 CSS 属性。
这就是问题所在……那个“很快”是什么时候?
据我所知,border-radius 最初是在 2002 年 [1] 推出的,现在是 2010 年,它仍然是草案。也许 W3C 应该采用更快的发布周期。
[1] 2002 年的规范(关于 border-radius)草案:http://www.w3.org/TR/2002/WD-css3-border-20021107/
不错的文章;我喜欢在 jQuery 中使 CSS 更强大的各种观点。
关于您的插件,有一个评论:您真的需要在其中使用 .each() 吗?我以为 .css 本身会遍历集合。只是好奇这是否是在解决另一个问题。
谢谢!
使用 .each() 是因为它是插件,它可能会传递多个选择器,例如
$(“#thing, #thing2).roundThis();
我非常确定这就是需要 .each() 的原因,但如果有人比我更聪明,并且想详细说明,请随意。
接近,如果传递集合,则会这样
像 $(‘a’).roundThis();
插件内部的“this”已引用您的 jQuery 元素堆栈。.css 也遍历元素,否则您无法执行 $(“a”).css();
因此,您构建了一个不必要的循环。删除 .each 应该不会影响功能。
或者您可以使用 jQuery UI CSS 框架。
一点也不。
jQuery UI 仍然使用相同的 moz 和 webkit css 属性,并且在 IE 中不起作用。
我想这依赖于 sizzle.js 引擎?
需要注意的是,通过 JavaScript 更改 CSS 属性在性能方面是一项非常昂贵的操作。只需删除/添加相关元素的类,并在样式表中声明 CSS,速度就会快得多。
话虽如此,在某些情况下(尽管很少),确实需要动态设置 CSS(而不是类),例如在创建像 css3please.com 这样的工具时。但是,我认为 jQuery 不应该像您提议的那样抽象专有的 CSS 属性。如果您真的想这样做,编写一个插件非常容易,就像您演示的那样。
不要忘记您无法为 CSS 类设置动画,因此您必须直接更改 CSS。
我认为 jQuery 堆叠的抽象越多,故障排除就越困难。考虑您前几天遇到的 delegate 属性和 jQuery 的 hover 事件(它不是真正的 JavaScript 事件,而是一个仅在某些情况下有效的抽象):如果您是 jQuery 新手程序员,并且对 JavaScript 和浏览器事件的了解不深,那么抽象内容和底层实际发生的事情之间的区别可能并不那么明显。我可以想象有人会花费大量时间试图解决一个问题,而如果hover事件没有作为mouseenter和mouseleave.
我不是想回复您,Matthias,而是想回复这篇文章,特别是 Chris。
每次我使用这些东西时,我都会感到难过,因为并非所有用户/客户都启用了 JavaScript。是不是这样?
大多数人都有。我想不出哪款浏览器在出厂时禁用了 Javascript,因此用户必须有意识地禁用它或将其作为公司/组织范围内的强制措施禁用。
除此之外,优雅降级也无可厚非。Javascript 由于未启用而无法圆角?客户看到的是方形角。这是目前无数文章的主题,我个人也同意。方形、圆形……归根结底,该网站对于 2% 禁用了 Javascript 的用户来说仍然非常可用。
好文章!但如果半径也可以作为参数传递,那就更好了。
毕竟我们是在进行抽象;)
@Ingo Wedler
那些禁用了 JavaScript 的人真的不在乎(知道?)这种 UI 体验 :)
这正是我开始编写那部分内容时想要做的事情,然后显然我变得懒惰了=)。
我更新了文章。
不错的方法,但使用 JS 执行此操作很繁重。我使用 Compass/Sass 使我的样式表恢复正常。
http://www.slideshare.net/pengwynn/css-metaframeworks-king-of-all-media/100
Compass 可以与任何框架一起使用,因为它只是输出 CSS。
补充一点——Chrome 现在接受 border-radius CSS 属性以及 -webkit-border-radius 属性。
很棒的教程,Chris
哪个版本的 Chrome 支持它?
我想知道如果我同时定义了这两个属性,哪个属性会生效?
迟早我们不再需要专有选择器了。耶!!!/o/
回到上个世纪的旧时代,我记得用JS表示法来写CSS是比较常见的。我可能还保留着一本关于这方面的书(我有点囤积癖)。
当我们说“保持CSS和JS分离”时,我们实际上是简写为“保持表现层和功能分离”……在一般情况下,这两者是等价的。
但是。
没有任何理由不能使用JavaScript表示法来表达你的表现层。事实上,用JavaScript编写所有你的“渐进增强”表现层,并利用jQuery,是完全合法的(甚至可能是可取的)。只要确保你保持表现层与行为分离。
我意识到我在这里有点“激进”,但我认为这种方法有其优点。特别是如果你编写插件来处理圆角(将CSS与IE兼容代码整合到一个调用中)和其他常见的样式处理。即使在CSS 3在所有地方完全实现的神话世界中,我也会建议这样做。
我在TextMate中添加了一个代码片段,以帮助我生成产生酷炫的CSS3边缘效果所需的冗长代码。
我只需要输入
rounded ⇥
它就会插入
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
-khtml-border-radius: 3px;
border-radius: 3px;
不错。你可以使用镜像占位符使代码片段更灵活。
-moz-border-radius: ${1:3px};
-webkit-border-radius: $1;
-khtml-border-radius: $1;
border-radius: $1;
在我看来,将像opacity这样的属性包含到库中是有意义的,因为它对于动态效果(“淡入淡出”)是必需的。但是,你是否希望动态更改border-radius呢?
不幸的是,等待某个东西成为标准后再让jQuery实现它有点没有意义,因为要让东西通过提议推荐阶段需要很长时间。
例如,CSS2.1直到2009年9月8日才达到候选推荐状态(也许它在某个时候被升级,然后又降级,所以这可能解释了原因)。因此,jQuery包含像border-radius这样的东西并没有错,即使它不是“官方”标准——因为它在未来很多年内可能都不会“正式”成为标准。
这是一个绕过CSS验证的好方法。谢谢。
感谢您提供的优秀插件链接,现在IE中的圆角问题已解决,感谢Chris提供的链接和Dave Methvin提供的插件。
我更喜欢使用插件,直到跨浏览器问题得到解决,这样我的访问者就不会错过乐趣。
为了使圆角在IE中正常工作,是否值得在Photoshop中制作图像并将其设置为div的顶部和底部?