如何从 CSS 选择器中提取类名
How to extract class names from a CSS selector?
故事:
我目前正在构建一个 ESLint 规则,以警告在 CSS 选择器定位器中使用面向引导布局和角度的技术类。目前,我在字符串方法中使用了一个简单的子字符串:
for (var i = 0; i < prohibitedClasses.length; i++) {
if (node.arguments[0].value.indexOf(prohibitedClasses[i]) >= 0) {
context.report({
node: node,
message: 'Unexpected Bootstrap class "' + prohibitedClasses[i] + '" inside a CSS selector'
})
}
但事实证明,它并不可靠。例如,它会在 CSS 选择器上抛出错误 2 次.col-sm-offset-11
报告要使用的col-sm-offset-1
和col-sm-offset-11
。我可以想象它可以很容易地在使用多个伪类的更复杂的选择器上中断。
问题:
从 CSS 选择器中提取类名的最可靠方法是什么?
以下是我们应该涵盖的示例测试列表(有待改进):
.col-sm-push-4 // -> ['col-sm-push-4']
.myclass.col-lg-pull-8 // -> ['myclass', 'col-lg-pull-8']
[class*='col-md-offset-4'] // -> []
[class$=col-md-offset-11] // -> []
[class~="col-md-10"] .myclass // -> ['col-md-10', 'myclass']
.col-md-10,.col-md-11 // -> ['col-md-10', 'col-md-11']
请注意,我们需要跳过^=
,$=
并*=
部分类过滤器值,留下~=
(感谢您的评论)。
有一个
专门为问题包设计的node-css-selector-parser
缺少"如何使用它"部分来提取类名。填补空白,这是我如何将其应用于问题的方法。
使用 node-css-selector-parser
,我们可以解析一个 CSS 选择器,并根据结果类型分析与点一起使用的类名(例如 .myclass
) 和属性选择器中使用的类名(例如 [class*=test]
):
// setup up CSS selector parser
var CssSelectorParser = require('css-selector-parser').CssSelectorParser
var parser = new CssSelectorParser()
parser.registerSelectorPseudos('has', 'contains')
parser.registerNestingOperators('>', '+', '~')
parser.registerAttrEqualityMods('^', '$', '*', '~')
parser.enableSubstitutes()
function extractClassNames (rule) {
var classNames = []
// extract class names defined with ".", e.g. .myclass
if (rule.classNames) {
classNames.push.apply(classNames, rule.classNames)
}
// extract class names defined in attributes, e.g. [class*=myclass]
if (rule.attrs) {
rule.attrs.forEach(function (attr) {
if (attr.name === 'class') {
classNames.push(attr.value)
}
})
}
return classNames
}
module.exports = function (cssSelector) {
try {
var result = parser.parse(cssSelector)
} catch (err) {
// ignore parsing errors - we don't want it to fail miserably on a target machine during a ESLint run
console.log('Parsing CSS selector: "' + cssSelector + '". ' + err)
return []
}
// handling empty inputs
if (!result) {
return []
}
var classNames = []
if (result.type === 'ruleSet') {
var rule = result.rule
while (rule) {
classNames.push.apply(classNames, extractClassNames(rule))
rule = rule.rule
}
} else if (result.type === 'selectors' && result.selectors) {
result.selectors.forEach(function (selector) {
var srule = selector.rule
while (srule) {
classNames.push.apply(classNames, extractClassNames(srule))
srule = srule.rule;
}
})
}
return classNames
}
(使用standard
代码样式 - 因此,例如,行尾没有;
)
事实证明,这对我有用,希望能帮助其他人解决类似的问题。请注意,在这种状态下,此代码还将提取传递到^=
、$=
和*=
的分部类值,理想情况下需要跳过这些值。
相关文章:
- Windows8应用程序(html&Javascript):从图片库(除了文件选择器)显示图像的另一种方式
- 在动态创建的元素上获取对特定选择器的引用
- AngularJS-在JSON选择器中使用变量名
- 每当您在选择器内移动鼠标时,悬停功能就会重复
- 使用CSS或js,使用动态选择器选择任意li的下一个元素
- jQuery最近父级的数据属性选择器
- 为什么不'在JQuery中找到第二个css选择器的工作
- 为什么 .focus() 不起作用,而 .css(“color”,“red”) 在同一个选择器上起作用
- jquery IE7中的第n个选择器
- Webdriver.io pageObject模式-通过传递参数来定义元素选择器
- jquery日期选择器年份范围默认值
- jquery日期选择器失去了交互性
- 正在搜索JavaScript日期选择器滑块
- 如何将返回的值应用于多个不同位置的多个选择器
- 在使用java使用dropbox选择器从dropbox中提取文件后,如何将文件存储在服务器中
- 从属性选择器中提取值
- 如何解析和提取CSS选择器作为字符串
- 我将如何提取月和年从月年选择器,我使用jquery
- 如何从 CSS 选择器中提取类名
- 当数据没有选择器时,如何从网页中提取数据?