总结:这个函数返回一个所有重复类名的有序列表,可以很容易地用于合并类。
首先,获取一个有用的重复列表:
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]) 访问具有一组类名的所有元素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"));