使用jQuery / Javascript合并css类

时间:2011-10-04 20:01:24

标签: javascript jquery html css

我有问题。我有一堆网页,大量使用多个css类。

<div class="class1 class2 class3">foo</div>

不幸的是,我有一个“浏览器”(缺少更好的术语),无法以这种方式处理多个css类。

我可以使用multiple classes识别所有元素,但现在我需要创建合并它们的新类。第一次尝试是将所有样式内联到样式属性中,但这太慢了,并且不必要地使文档膨胀。

我现在想要做的是找到一个包含多个类的元素。创建一个组合的新类,并将元素类替换为新创建的类,以及具有相同类组合的任何其他元素。

关于如何最好地解决这个问题的任何想法。

3 个答案:

答案 0 :(得分:2)

遍历所有标签。将类名拆分为数组。对其进行排序以使其成为可预测的顺序。将字符串重新加入。

$(document).ready(function() {
    var classList = {};
    $("*").each(function() {
        var temp;
        if (this.className) {
            temp = this.className.split(" "); // split into array
            temp.sort();                      // put in predictable order
            this.className = temp.join("");   // put class name back without spaces
            classList[this.className] = true; // add to list
        }
    });
    // classList object contains full list of all classNames used
});

仅供参考,您有一个支持jQuery的浏览器似乎很奇怪,但不支持多个类名的CSS样式。你确实意识到你将不得不提供完全不同的样式表来解决连接的名称,对吗?而且,如果您可以更改样式表,我会想知道为什么您无法更改HTML。

工作实施:http://jsfiddle.net/jfriend00/uPET7/

答案 1 :(得分:1)

摘要:此函数返回所有重复类名的有序列表,可以很容易地用于合并类。

首先,获取有用的重复列表:

var multi = {};

$("*[class]").each(function(){
    var class = this.className.replace(/^\s+|\s+$/g,"").replace(/\s+/g,".");
    if(!/\./.test(class)) return; //Ignore single classes
    if(multi[class]){
        multi[class]++;
    } else {
        multi[class] = 1;
    }
});

//Now, merge duplicates, because .class1.class2 == .class2.class1
var multi_nodup = {};
for(var classes in multi){
    var a_classes = classes.split(".");
    var a_classes = a_classes.sort();
    var a_classes = a_classes.join(".");
    if(multi_nodup[a_classes]){
        multi_nodup[a_classes] += multi[classes];
    } else {
        multi_nodup[a_classes] = multi[classes]
    }
}
//Now, multi_npdup is a map of all duplicate classnames

var array_multi = [];
for(var classes in multi_nodup){
    array_multi.push([multi_nodup[classes], classes]);
}
array_multi.sort(function(x,y){return y[0]-x[0]});
//array_multi is an array which looks like [["class1.class2.class2", 33],
//             ["class3.class4", 30], ...]
// = A list, consisting of multiple class names, where multiple classnames
// are shown, together with the nuber of occurences, sorted according to
// the frequence

执行我的函数,并输出变量array_multi。这将显示多个类名的映射,以便您可以相应地替换多个类名。

由于我存储类名的特殊方式,您可以使用$("." + array_multi[n][0])来访问所有具有一组classname的元素,该类名等于 n 中描述的集合array_multi中的位置。

可读输出的示例:

//Overwrites current document!
var list = "";
for(var i=0; i<array_multi.length; i++) list += array_multi[i][0] + "\t" + array_multi[i][1];
document.open();
document.write("<pre>"+list+"</pre>")
document.close();

自动转换

通过将所有单独的类属性添加到JavaScript字符串并将其添加到对象来自动合并类名i的方法。这是获取确切CSS属性的最可靠方法,因为尝试通过document.styleSheets对象获取类名可能会产生稍微不同的结果。例如:

var classStyle = {};
classStyle["class1"] = "border:1px solid #000;";
classStyle["class2"] = "color:red";

//Make sure that each declaration ends with a semicolon:
for(var i in classStyle) if(!/;$/.test(classStyle[i])) classStyle[i] += ";";

//Initialise
var all_styles = {};
for(var i=0; i<array_multi.length; i++){
    all_styles[array_multi[i][1]] = "";
}

//This loop takes definition precedence into account
for(var currentCName in classStyle){
    var currentClass = new RegExp("(?:^|\\.)" + currentCName + "(?:\\.|$)");

    // Rare occasion of failure: url("data:image/png,base64;....")
    var separateProps = classStyle[currentCName].split(";");
    var prop_RE = {};
    for(var p=0; p<separateProps.length; p++){
        var cssProperty = separateProps[p];
        if(!/:/.test(cssProperty)) continue; //Invalid CSS property
        prop_RE[cssProperty] = new RegExp("(^|;)\\s*" + cssProperty.match(/(\S+)\s*:/gi)[1] + "\\s*:[^;]+;?", "gi");
    }

    for(var class in all_styles){
        if(currentClass.test(class)){
            for(var k in prop_RE){
                all_styles[class] = all_styles[class].replace(prop_RE[k],"$1") + k;
            }
        }
    }
}

//To finish off:
var allClassesToString = "";
for(var class in all_styles){
    var newClass = class.replace(/\./g, "_");
    $("."+class).each(function(){
        this.className = newClass;
    });
    allClassesToString += "."+newClass + "{" + all_styles[class] + "}\n";
}

// allClassesToString <------- This variable now holds a string of all duplicate CSS classes!
//Example:
var style = $("<style>");
style.text(allClassesToString);
style.appendTo($("head:first"));

答案 2 :(得分:0)

实现这一目标似乎并不疯狂,

循环遍历每个具有多个类的元素。对类进行排序(只要它是一致的无关紧要)然后将它们合并在一起以创建新类。保留所有新css类的列表,并在重复的情况下检查它们。

要从元素中获取所有样式,请参阅here