在CSS中使用Javascript

是否有可能在CSS内使用JavaScript?

如果是这样,你能举个简单的例子吗?

IE和Firefox都包含从CSS执行JavaScript的方法。 Paolo提到,IE中的一种方式是expression技术,但也有一些比较隐晦的HTC行为 ,其中包含脚本的独立XML通过CSS加载。 存在使用XBL的类似的Firefox技术。 这些技术不直接从CSS执行JavaScript,但效果是一样的。

HTC与IE

使用像这样的CSS规则:

 body { behavior:url(script.htc); } 

并在该script.htc文件中有这样的东西:

 <PUBLIC:COMPONENT TAGNAME="xss"> <PUBLIC:ATTACH EVENT="ondocumentready" ONEVENT="main()" LITERALCONTENT="false"/> </PUBLIC:COMPONENT> <SCRIPT> function main() { alert("HTC script executed."); } </SCRIPT> 

HTC文件在事件ondocumentready上执行main()函数(参考HTC文档的准备情况)。

XBL与Firefox

Firefox使用XBL支持类似的XML脚本执行攻击。

使用像这样的CSS规则:

 body { -moz-binding: url(script.xml#mycode); } 

并在你的script.xml中:

 <?xml version="1.0"?> <bindings xmlns="http://www.mozilla.org/xbl" xmlns:html="http://www.w3.org/1999/xhtml"> <binding id="mycode"> <implementation> <constructor> alert("XBL script executed."); </constructor> </implementation> </binding> </bindings> 

构造函数标签中的所有代码都将被执行(将代码包装在CDATA部分中的一个好主意)。

在这两种技术中, 代码不会执行,除非CSSselect器匹配文档中的元素 。 通过使用类似body东西,它会立即执行页面加载。

我想你可能会想到的是expressions或“dynamic属性” ,这是只有IE支持,并让你设置一个属性的JavaScriptexpression式的结果。 例:

 width:expression(document.body.clientWidth > 800? "800px": "auto" ); 

此代码使IE模拟它不支持的max-width属性。

所有考虑的事情,但是, 避免使用这些 。 他们是一个坏的,坏的东西。

为了便于您根据您提供的信息解决您的问题,我将假定您正在寻找dynamicCSS。 如果是这种情况,可以使用服务器端脚本语言来实现。 例如(我绝对喜欢做这样的事情):

styles.css.php:

 body { margin: 0px; font-family: Verdana; background-color: #cccccc; background-image: url('<?php echo 'images/flag_bg/' . $user_country . '.png'; ?>'); } 

这会将背景图像设置为存储在$ user_countryvariables中的任何值。 这只是dynamicCSS的一个例子; 组合CSS和服务器端代码时,实际上有着无限的可能性。 另一种情况是,像允许用户创build自定义主题,将其存储在数据库中,然后使用PHP来设置各种属性,如下所示:

user_theme.css.php:

 body { background-color: <?php echo $user_theme['BG_COLOR']; ?>; color: <?php echo $user_theme['COLOR']; ?>; font-family: <?php echo $user_theme['FONT']; ?>; } #panel { font-size: <?php echo $user_theme['FONT_SIZE']; ?>; background-image: <?php echo $user_theme['PANEL_BG']; ?>; } 

但是,再一次,这仅仅是一个非常头脑的例子。 通过服务器端脚本来利用dynamicCSS的力量可以导致一些非常不可思议的东西。

IE支持CSS expression式

 width:expression(document.body.clientWidth > 955 ? "955px": "100%" ); 

但它们不是标准的,不能跨浏览器移植。 如果可能的话避免它们。 自IE8以来,它们已被弃用。

对于更新的解决scheme,使用Vue。

  var vue = new Vue({ el : "#app", data: { styleObject: { color: 'red', fontSize: '20px' }, activeColor: 'blue', activeColor2: 'green', fontSize: '30px' }, methods : { color: function (color) { this.activeColor2 = color; } }, mounted: function () { if(1 > 0) { this.color('gray'); } } }) 
 <script src="vue@2.5.2/dist/vue.js"></script> <ul id="app" :style="styleObject"> <li>test</li> <li :style="{color: activeColor2, fontSize: fontSize}">test</li> <li>test</li> <li>test</li> <li :style="{color: activeColor, fontSize: fontSize}">test</li> <li>test</li> <li>test</li> </ul> 

我碰到类似的问题,并开发了两个独立的工具来完成这个工作:

  • CjsSS.js是一个支持IE6的Vanilla Javascript工具(所以不需要外部依赖)。

  • ngCss是一个支持Angular 1.2+的Angular Module + Filter + Factory(又名:插件)(回到IE8)

这两个工具集都允许您在STYLE标记或外部* .css文件中执行此操作:

 /*<script src='some.js'></script> <script> var mainColor = "#cccccc"; </script>*/ BODY { color: /*{{mainColor}}*/; } 

而这在你的页面style属性中:

 <div style="color: {{mainColor}}" cjsss="#sourceCSS">blah</div> 

要么

 <div style="color: {{mainColor}}" ng-css="sourceCSS">blah</div> 

注意:在ngCss中,你也可以用$scope.mainColor代替var mainColor

默认情况下,Javascript是在沙盒IFRAME中执行的,但是由于您自己创build了CSS并将其托pipe在自己的服务器上(就像* .js文件一样),所以XSS不是问题。 但沙箱提供了更多的安全性和安心。

CjsSS.js和ngCss位于其他工具之间,完成类似的任务:

  • LESS , SASS和Stylus都只是预处理器,并要求您学习一种新的语言,并打乱您的CSS。 基本上他们扩展了CSS新的语言function。 所有这些都只限于针对每个平台开发的插件,而CjsSS.js和ngCss都允许您在CSS中直接包含任何Javascript库<script src='blah.js'></script>

  • AbsurdJS看到了相同的问题,并且走上了与上述预处理器完全相反的方向; 而不是扩展CSS,AbsurdJS创build了一个Javascript库来生成CSS。

CjsSS.js和ngCss占据了中间地带; 你已经知道了CSS,你已经知道Javascript,所以让他们以简单直观的方式一起工作。

没有任何传统意义上的“CSS内部”。

这原来是一个非常有趣的问题。 有超过一百个属性被设置,你会认为你可以键入.clickable {onclick:“alert('hi!');” ; }在你的CSS,它会工作。 这很直观,这很有道理。 这对于dynamic生成大量用户界面的猴子补丁非常有用。

问题:
CSS警察以他们无限的智慧,在performance行为之间划出了中国墙。 任何有意不被CSS支持的HTML标签。 ( 完整属性表 )

最好的解决方法是使用jQuery,它在后台设置一个解释引擎来执行你正在用CSS做的事情。 看到这个页面: 将Javascript Onclick添加到.css文件 。

祝你好运。