我正在使用工具并卡住。
我正在访问网站的样式表对象,只想获取“ CSSFontFaceRule”。我已经解决了,但是返回的对象中的输出是一个巨大的字符串。我想将字符串细分为一个on对象。 我还创建了一个小提琴:http://jsfiddle.net/9eoytc6v/1/
这是我的现状:
@font-face {font-family: "Test-Book";
src:
url("https://fontserver.xyz/test.eot?#iefix") format("embedded-opentype"),
url("https://fontserver.xyz/test.woff2") format("woff2"),
url("https://fontserver.xyz/test.woff") format("woff"),
url("https://fontserver.xyz/test.ttf") format("truetype"),
url("https://fontserver.xyz/test.svg#Test-Book") format("svg");
}
let fonts = {};
function getFontPairs(obj) {
let object = obj || {},
stylesheet = document.styleSheets,
rule = null,
length = stylesheet.length,
j;
while (0 <= --length) {
rule = stylesheet[length].rules || stylesheet[length].cssRules || [];
j = rule.length;
while (0 <= --j) {
if (rule[j].constructor.name === "CSSFontFaceRule") {
let sourcesString = rule[j].style.src;
let re = /\s*(?:,|$)\s*/;
let sources = sourcesString.split(re);
let final = [];
sources.forEach(function(element){
let reg = /[ ,]+/;
let srcArray = element.split(reg);
srcArray = srcArray.reverse();
final.push(srcArray);
});
object[rule[j].style.fontFamily] = final;
}
}
}
return object;
}
getFontPairs(fonts);
console.log(fonts);
我尝试使用数组,但是我的输出有点混乱: Current array solution
相反,我想实现以下目标: Expected object solution
所以我现在不擅长RegEx,我也想剥离url("")
和format("")
。
感谢您的帮助。也许有人可以帮忙提供更高效率的代码版本。
答案 0 :(得分:0)
只需匹配每个源字符串的url和格式。一个简单的正则表达式就可以了,正则表达式只匹配双引号或单引号中的内容,正则表达式的示例可以匹配网址:
/url\(.(.+?).\)/
这意味着匹配url(.
和.)
之间的任何内容。括号被转义,因此正则表达式不会将它们视为一个组。 .
(任何字符)代表引号(双精度或单精度)。 (.+?)
是我们所感兴趣的URL,它使用的是非预备模式?
,因此它将匹配尽可能少的字符,否则您可能会得到如下URL: https://fontserver.xyz/test.eot?#iefix") format("embedded-opentype
,从第一个引号到第二个引号匹配(超出url并输入格式区域)。
然后,要构造对象,只需reduce
将源分成一个像这样的对象:
let sourcesObj = sources.reduce((acc, source) => { // for each source
let format = source.match(/format\(.(.+?).\)/)[1], // get the format
url = source.match(/url\(.(.+?).\)/)[1]; // and the url
acc[format] = { format, url }; // add them to the sourcesObj under the key format ({ format, url } is short for { format: format, url: url })
return acc;
}, {});
完整代码:
function getFontPairs() {
let object = {},
stylesheet = document.styleSheets,
rule = null,
length = stylesheet.length,
j;
while (0 <= --length) {
rule = stylesheet[length].rules || stylesheet[length].cssRules || [];
j = rule.length;
while (0 <= --j) {
if (rule[j].constructor.name === "CSSFontFaceRule") {
let sourcesString = rule[j].style.src;
let sources = sourcesString.split(/\s*,\s*/);
let sourcesObj = sources.reduce((acc, source) => {
let format = source.match(/format\(.(.+?).\)/)[1],
url = source.match(/url\(.(.+?).\)/)[1];
acc[format] = { format, url };
return acc;
}, {});
object[rule[j].style.fontFamily] = sourcesObj;
}
}
}
return object;
}
let fonts = getFontPairs();
console.log(fonts);
注意:URL和格式正则表达式的一种更复杂的替代方法是:
/url(\s*["'](.+?)["']\s*)/
处理诸如url( "..." )
之类的空格的情况,并寻找引号("
或'
)以确保安全。同样的东西也可以应用于正则表达式。
编辑:
如果某些源缺少字段,则只需在访问组[1]
之前检查格式和url正则表达式是否确实匹配某些内容:
let sourcesObj = sources.reduce((acc, source) => {
let format = source.match(/format\(.(.+?).\)/),
url = source.match(/url\(.(.+?).\)/);
if(format && url) { // if and only if the two regexes matched what they are intended for
acc[format[1]] = { format: format[1], url: url[1] }; // add the current source to 'sourcesObj' (notice the '[1]' is used after we've made sure that neither 'format' nor 'url' are 'null')
}
return acc;
}, {});
编辑2:
缺少format
时,请替换为"Unknown"
:
let sourcesObj = sources.reduce((acc, source) => {
let format = source.match(/format\(.(.+?).\)/),
url = source.match(/url\(.(.+?).\)/)[1];
format = format? format[1]: "Unknown";
acc = { format, url };
return acc;
}, {});