我有问题。我有一堆网页,大量使用多个css类。
<div class="class1 class2 class3">foo</div>
不幸的是,我有一个“浏览器”(缺少更好的术语),无法以这种方式处理多个css类。
我可以使用multiple classes识别所有元素,但现在我需要创建合并它们的新类。第一次尝试是将所有样式内联到样式属性中,但这太慢了,并且不必要地使文档膨胀。
我现在想要做的是找到一个包含多个类的元素。创建一个组合的新类,并将元素类替换为新创建的类,以及具有相同类组合的任何其他元素。
关于如何最好地解决这个问题的任何想法。
答案 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。
答案 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