在所有CSS选择器前添加内容

15
有没有一种文本过滤器或javascript/jquery函数可以在样式表中的所有CSS选择器前面添加某些内容?我正在尝试仅影响Twitter Bootstrap中的一个div,但它会影响到其外部的侧边栏,有没有办法解决这个问题?(我不想使用iframe。)
编辑:
我所需要做的就是能够在CSS文件的每个选择器前面添加ID“#content”。

7
嗯...你为什么不想个办法来唯一标识这个div呢?改变整个页面的样式似乎不是个好主意,因为它可能会破坏其他东西。 - nico
完全同意 @nico 的观点。请发布您的网站或一个 fiddle,肯定有更好的方法。 - Mike Robinson
它不会破坏页面,我想将 Twitter Bootstrap 的 CSS 应用于单个 DIV,我只想在 bootstrap.css 文件中前置 CSS。 - Ray
5个回答

28

根据您在sabithpocker的回答下方的评论,我了解到您想要静态地修改CSS而不是动态地改变样式。我认为这最容易使用正则表达式实现:

查找:([,|\}][\s$]*)([\.#]?-?[_a-zA-Z]+[_a-zA-Z0-9-]*)
替换为:$1#content $2

Regex详解

  • ([,|\}][\s$]*) - 查找前面样式中的 },,后面跟随空格(空格/制表符:\s,换行符: $)。闭合大括号或逗号可以防止正则表达式查找样式主体内部。
  • [\.#]? - 如果存在,则匹配样式名称中的起始 #.
  • -?[_a-zA-Z]+ - CSS样式名称可以以下划线或字母开头。此外,样式名称可以以破折号为前缀。
  • [_a-zA-Z0-9-]* - 匹配样式名称的剩余部分。这可以省略,但知道被修改的所有样式的样式名可能会很有用。
  • $1#content $2 - 保留 }(或 ,)和空格原样不变 ($1),然后插入您的文本 #content(注意空格),随后是样式名称 ($2)。

我在Notepad++中测试过,它可以在我的样式表上正常工作。
需要注意的是,如果您的CSS没有压缩(并且跨行),您将需要支持多行正则表达式的编辑器(Notepad++支持)。


1
@Raymond - 已更新以包括逗号分隔的名称。(\} 只需要更改为 [,|\}]) - RustyTheBoyRobot
1
不错,但它并不能做到所有的事情(例如:在媒体查询中放置一个a标签)。 - David Sherret
1
关于我上面的评论,您可以执行额外的 css = css.replace(/(@media[^{]+{[\s$]*)([\.#]?-?[_a-zA-Z]+[_a-zA-Z0-9-]*)/, "$1" + prependClass + " $2"); 来捕获这些情况。 - David Sherret
@MarianoMartinezPeck - 你需要在最后一个正斜杠后面加上 'g' 来使用全局匹配:/regex/g - RustyTheBoyRobot
1
您好。我在处理颜色代码时遇到了问题,当颜色以字母开头时(如果以数字开头则正确)。相关的 CSS 代码如下: background: linear-gradient(to bottom, #ae9e9e, #454545);。除了以字母开头的颜色外,使用 RGB 也无法正常工作。在所有情况下,都会出现类似于 background: linear-gradient(to bottom, #myDiv #ae9e9e, #454545) 的结果。有什么想法吗? - Mariano Martinez Peck
显示剩余11条评论

7
Improved upon RustyTheBoyRobot and BoltClock♦的答案,增加了对注释和媒体查询的支持。
查找: ([,|\}][\s$]*)((?|\/\/.*[\s$]+|.*\/\*.*\*\/[\s$]*|@media.*\{[\s$]*|)*)([\.#]?-?[_a-zA-Z]+[_a-zA-Z0-9-]*) 替换为: $1$2 #content $3

编辑

已经有人指出我提供的代码只适用于PHP。
这里是一个改进版,可以在Javascript和PHP中使用。 正则表达式模式*
(^(?:\s|[^@{])*?|[},]\s*)(\/\/.*\s+|.*\/\*[^*]*\*\/\s*|@media.*{\s*|@font-face.*{\s*)*([.#]?-?[_a-zA-Z]+[_a-zA-Z0-9-]*)(?=[^}]*{)

完整示例*

var outputString = inputString.replace(
    /(^(?:\s|[^@{])*?|[},]\s*)(\/\/.*\s+|.*\/\*[^*]*\*\/\s*|@media.*{\s*|@font-face.*{\s*)*([.#]?-?[_a-zA-Z]+[_a-zA-Z0-9-]*)(?=[^}]*{)/g,
    "$1$2 #content $3"
);

这也应该解决@Mariano Martinez Peck关于background: linear-gradient(to bottom, #ae9e9e, #454545);的问题,以及@font-face的问题。


我在编译时遇到了一个错误,它应该是 ?| 还是 ?: - ericpeters
哦,?| 是 PCRE 的东西,在 Java 中不支持。 - ericpeters
尝试在JS中使用此代码时出现错误。我正在尝试以下内容:".{} /*.table tbody > tr > td {font-family: verdana; font-size: small} */ .researchCompanyReportTableControls { display: none; } ".replace(/([,|\}][\s$]*)((?|\/\/.*[\s$]+|.*\/\*.*\*\/[\s$]*|@media.*\{[\s$]*|)*)([\.#]?-?[_a-zA-Z]+[_a-zA-Z0-9-]*)/g, "$1" + "$2" + "#myDiv" + " $3");但是它会因为无效组而失败。有什么想法吗?看起来似乎不喜欢?| - Mariano Martinez Peck

4

使用SCSS可以更轻松地完成这项任务。只需将现有的CSS嵌套到一个#my-new-selector { ... }中,然后通过一个SCSS to CSS编译器运行它(有在线工具可以做到这一点,无需安装任何软件)。


1
现在,这是一种更加一致和容易的方法。正则表达式在系统之间非常棘手,并且你会遇到很多边缘情况,但是SCSS解析并理解CSS,所以除非SCSS编译器有问题,否则你很可能会得到你想要的结果。 - Carlos Sanchez

1

解决方法(如果确实需要这样做):

  1. 等待窗口加载完成并应用所有样式
  2. 获取您想要应用的元素样式
  3. 获取它们的样式并将其应用于内联

对于跨浏览器实现,可以使用下面展示的jquery插件:

$('#mydiv *').each(function(){
    $(this).css($(this).getStyleObject());
    });

然后禁用原始样式表

document.stylesheets[n].disabled = true;
//or use this : $('link[title=mystyle]')[0].disabled=true;

//n should be index of style sheet -- counts external + internal style sheets

插件:

/*
 * getStyleObject Plugin for jQuery JavaScript Library
 * From: http://upshots.org/?p=112
 */

(function($){
    $.fn.getStyleObject = function(){
        var dom = this.get(0);
        var style;
        var returns = {};
        if(window.getComputedStyle){
            var camelize = function(a,b){
                return b.toUpperCase();
            };
            style = window.getComputedStyle(dom, null);
            for(var i = 0, l = style.length; i < l; i++){
                var prop = style[i];
                var camel = prop.replace(/\-([a-z])/g, camelize);
                var val = style.getPropertyValue(prop);
                returns[camel] = val;
            };
            return returns;
        };
        if(style = dom.currentStyle){
            for(var prop in style){
                returns[prop] = style[prop];
            };
            return returns;
        };
        return this.css();
    }
})(jQuery);

有没有办法将它导出,以便我可以只保存 .css 文件?我更希望这是一个静态文件。 - Ray
你为什么需要那个,你能解释一下你想要实现什么吗? - sabithpocker
我想将 Twitter Bootstrap CSS(bootstrap.css)应用于单个 div,目前它影响页面上的所有内容。 - Ray

0

不,样式表只是一个复制粘贴的文件。你必须用唯一标识符包装所有你想要的内容,然后使用这个唯一标识符引用它。


我有一个唯一标识符,问题是所有的CSS都不匹配它,我需要一种方法来处理文本并在每个选择器前添加 #content - Ray
CSS以文本形式出现,然后在浏览器中作为对象保存在document.stylesheets数组中,现代浏览器有直接攻击它们的方法。请查看兼容性和可用函数的怪癖http://www.quirksmode.org/dom/w3c_css.html。 - sabithpocker
@sabithpocker 我知道CSS的工作原理,我想要一个特定于CSS格式的文本文件文本过滤器,使用该过滤器,我想在该文本文件中的所有选择器前添加一个前缀。 - Ray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接