如何在Javascript中计算css规则优先级?
我创建了这个代码来计算css规则的优先级如何在Javascript中计算css规则优先级?,javascript,css,Javascript,Css,我创建了这个代码来计算css规则的优先级 var selectorText = "body"; A = selectorText.match(/#/gm); // id A = !A ? 0 : A.length; B1 = selectorText.match(/\\./gm); // class B1 = !B1 ? 0 : B1.length; B2 = selectorText.match(/[[]/gm); // attribute selector B2 = !B2 ? 0 : B2
var selectorText = "body";
A = selectorText.match(/#/gm); // id
A = !A ? 0 : A.length;
B1 = selectorText.match(/\\./gm); // class
B1 = !B1 ? 0 : B1.length;
B2 = selectorText.match(/[[]/gm); // attribute selector
B2 = !B2 ? 0 : B2.length;
B3 = selectorText.match(/[\\w\\d_\\s^]:(?!:)/gm); // pseudo třída
B3 = !B3 ? 0 : B3.length;
B = B1 + B2 + B3;
C1 = selectorText.match(/::/gm); // pseudo element
C1 = !C1 ? 0 : C1.length;
C2 = selectorText.match(/\\w+[$\\s#\\.:\\[]/gm); // element
C2 = !C2 ? 0 : C2.length;
C = C1 + C2;
A *= 10000;
B *= 100;
alert(C)
选择器中的匹配项(A、B或C)不得超过100个。
出于某种原因,C的结果是0(但我使用“body”选择器)。你能建议如何纠正最后一场比赛吗?你也看到代码中有错误吗
注:
最初的问题只说明了“body”选择器,但我认为任何选择器或多个选择器都是这样的:“div#menu ul li、div#id、div.class”选择器可以包含伪类、伪元素、属性选择器。在C2正则表达式的情况下,我试图找到最后一个字符串中的元素总数为5个元素(那么C2应该是5个元素)。
selectorText
不包含::
,C1=selectorText.match(/::/gm)
应返回null
<代码>C1=!C1?0:C1.5cm代码>返回0
C2=selectorText.match(/\\w+[$\s\\\.:\\[]/gm)
返回null
,C2=!C2?0:C2.length;
返回0
;C=C1+C2;
等于0
;即0+0=0
最初的问题只是“身体”选择器,但我想 任何选择器或多个选择器如下:“div#menu ul li,div#id, div.class“选择器可以包含伪类、伪元素、, 属性选择器。在C2正则表达式的情况下,我试图找到 最后一个字符串中的元素总数为5个元素 (那么C2应该是5) 您可以使用
.split()
和RegExp
/,|\s/
在,
字符;.map()
,.filter(Boolean)
删除空字符串,.match()
和RegExp
/^[a-z]+(?=[.#:\s]$)/i
匹配元素
var selectorText=“div#menu ul li,div#id,div.class”;
C2=selectorText.split(/,|\s/).filter(布尔值)
.map(el=>el.trim().match(/^[a-z]+(?=[.#::\s]|$)/i)[0]);
console.log(C2);
selectorText
不包含:
,C1=selectorText.match(/::/gm);
应返回null
;C1=!C1?0:C1.length;返回0
;C2=selectorText.match(/\\w+[$\s\\:\[\\[]/gm)
返回null
,C2=!C2?0:C2.length;
返回0
;C=C1+C2;
等于0
;即0+0=0
最初的问题只是“身体”选择器,但我想
任何选择器或多个选择器如下:“div#menu ul li,div#id,
div.class“选择器可以包含伪类、伪元素、,
属性选择器。在C2正则表达式的情况下,我试图找到
最后一个字符串中的元素总数为5个元素
(那么C2应该是5)
您可以使用.split()
和RegExp
/,|\s/
在,
字符;.map()
,.filter(Boolean)
删除空字符串,.match()
和RegExp
/^[a-z]+(?=[.#:\s]$)/i
匹配元素
var selectorText=“div#menu ul li,div#id,div.class”;
C2=selectorText.split(/,|\s/).filter(布尔值)
.map(el=>el.trim().match(/^[a-z]+(?=[.#::\s]|$)/i)[0]);
console.log(C2);
首先,我需要解决如何解析多个选择器的问题。正如Oriol所说,我无法使用正则表达式解析多个选择器。此函数满足我的需要
String.prototype.findStrings = function (s = ',') {
var prev = null, prevEscaped = null, typq = null,
typp = null, depRB = 0, depSB = 0;
var obj = { length: 0,
results: { array: [], A: null, B: null, C: null }
};
var action = null;
if (s.constructor === Array)
{
action = 1;
}
else
{
if (typeof s === 'string' || s instanceof String)
action = 0;
}
if ( action === null)
return false;
for (var i=0; i<this.length; i++)
{
// not escaped:
if (!prevEscaped)
{ // not escaped:
switch (this[i])
{
case '\\':
prevEscaped = true;
prev = '\\'; // previous escaped
break;
case '"':
if (!typq)
{
typq = '"';
}
else if ( typq=='"' )
{ // end quotes
typq = null;
continue;
}
break;
case "'":
if (!typq)
{
typq = "'";
}
else if ( typq=="'" )
{ // end quotes
typq = null;
continue;
}
break;
}
}
else
{ // is escaped - do nothing
prevEscaped = false;
prev = null;
continue;
}
if (!typq) // no quotes block
{
switch (this[i])
{
case '(':
if (!typp)
typp = '('; // defines higher priority of () parenthesis
depRB++;
break;
case "[":
if (!typp)
typp = '[';
depSB++;
break;
case ")":
depRB--;
if (!depRB)
{
if ( typp == "(" )
{
typp = null; // end block of parenthesis
continue;
}
}
break;
case "]":
depSB--;
if (!depSB)
{
if ( typp == "[" )
{
typp = null; // end block of parenthesis
continue;
}
}
break;
}
}
if (typp) // commas inside block of parenthesis of higher priority are skipped
continue;
if (!action) // Separate by string s
{
if ( this[i] == s )
{
obj.results.array.push(i);
obj.length++;
}
}
else
{
}
// Block of no quotes, no parenthesis follows
} // end for
// Last item
obj.results.array.push(i);
obj.length++;
return obj;
};
/* Return array of strings */
String.prototype.splitFromArray = function (arr, autotrim = true) {
var prev = 0, results = [];
for (var i = 0; i<arr.length; i++)
{
var s = "";
s = this.substring(prev+1,arr[i]).trim();
results.push( s );
prev = arr[i];
}
return results;
};
很抱歉,示例中的选择器无效,但这只是说明解析。您可以编辑它以获得有效的选择器
添加搜索规则并不困难。首先,我需要解决如何解析多个选择器的问题。正如Oriol所说,我无法使用正则表达式解析多个选择器。此函数满足我的需要
String.prototype.findStrings = function (s = ',') {
var prev = null, prevEscaped = null, typq = null,
typp = null, depRB = 0, depSB = 0;
var obj = { length: 0,
results: { array: [], A: null, B: null, C: null }
};
var action = null;
if (s.constructor === Array)
{
action = 1;
}
else
{
if (typeof s === 'string' || s instanceof String)
action = 0;
}
if ( action === null)
return false;
for (var i=0; i<this.length; i++)
{
// not escaped:
if (!prevEscaped)
{ // not escaped:
switch (this[i])
{
case '\\':
prevEscaped = true;
prev = '\\'; // previous escaped
break;
case '"':
if (!typq)
{
typq = '"';
}
else if ( typq=='"' )
{ // end quotes
typq = null;
continue;
}
break;
case "'":
if (!typq)
{
typq = "'";
}
else if ( typq=="'" )
{ // end quotes
typq = null;
continue;
}
break;
}
}
else
{ // is escaped - do nothing
prevEscaped = false;
prev = null;
continue;
}
if (!typq) // no quotes block
{
switch (this[i])
{
case '(':
if (!typp)
typp = '('; // defines higher priority of () parenthesis
depRB++;
break;
case "[":
if (!typp)
typp = '[';
depSB++;
break;
case ")":
depRB--;
if (!depRB)
{
if ( typp == "(" )
{
typp = null; // end block of parenthesis
continue;
}
}
break;
case "]":
depSB--;
if (!depSB)
{
if ( typp == "[" )
{
typp = null; // end block of parenthesis
continue;
}
}
break;
}
}
if (typp) // commas inside block of parenthesis of higher priority are skipped
continue;
if (!action) // Separate by string s
{
if ( this[i] == s )
{
obj.results.array.push(i);
obj.length++;
}
}
else
{
}
// Block of no quotes, no parenthesis follows
} // end for
// Last item
obj.results.array.push(i);
obj.length++;
return obj;
};
/* Return array of strings */
String.prototype.splitFromArray = function (arr, autotrim = true) {
var prev = 0, results = [];
for (var i = 0; i<arr.length; i++)
{
var s = "";
s = this.substring(prev+1,arr[i]).trim();
results.push( s );
prev = arr[i];
}
return results;
};
很抱歉,示例中的选择器无效,但这只是说明解析。您可以编辑它以获得有效的选择器
添加搜索规则并不难。<>代码>选择文本> /代码>不包含代码>:/>代码>代码>匹配(//://GM)应该返回<代码> null <代码>。不能用正则表达式解析CSS。或者至少不这样。例如,考虑代码< > A,A,B,<代码>,其特异度为(1,0,0),但这表示(2,0,0)。。您不能在逗号处拆分,也不能单独计算每个部分,因为某些操作数有逗号。因此,您需要一个CSS解析器。@user1141649您需要一个用JS编写的CSS解析器来公开此信息。@Oriol我能不能从字符串中替换逗号,例如
var selectorText=“div#id,div.body;#a>:matches(.b,#c)”
对于某些字符,如“^”var selectorText=“div#id,div.body;#a>:匹配(.b ^#c)”;
我可以使用.replace搜索括号中的内容并替换它。@user1141649是否要替换括号中的逗号?这可能可行,但JS中的正则表达式无法处理递归,嵌套括号的数量可以是任意的。然后,您需要撤消替换以计算特定的Type的<代码> > b,y> C >代码> >不包含<代码>:/<代码> >代码>匹配(//://GM)应该返回<代码> null >代码>不能用正则表达式解析CSS。或者至少不是这样的。例如,考虑代码< > A,A,B,< /代码>,其特异度为(1,0,0),但这表示(2,0,0)。。您不能在逗号处拆分,也不能单独计算每个部分,因为某些操作数有逗号。因此,您需要一个CSS解析器。@user1141649您需要一个用JS编写的CSS解析器来公开此信息。@Oriol我能不能从字符串中替换逗号,例如var selectorText=“div#id,div.body;#a>:matches(.b,#c)”
对于某些字符,如“^”var selectorText=“div#id,div.body;#a>:匹配(.b ^#c)”;
我可以使用。替换以搜索方括号的内容