您好我一直在尝试使用PostCSS,并且在编写插件时遇到了一些困难,该插件会在找到某些CSS属性时添加新规则。
我想要实现的目标......
启动CSS:
.selector {
color: red;
not-yet-standard-property-a: 10px;
not-yet-standard-property-b: 20px;
}
在PostCSS插件之后:
.selector {
color: red;
not-yet-standard-property-a: 10px;
not-yet-standard-property-b: 20px;
}
.ie .selector {
standard-property-a: 10px;
standard-property-b: 20px;
}
每当我看到其中一条not-yet-standard-property-*
时,我就可以轻松添加新规则...
return function (css) {
css.walkRules(function (rule) {
rule.walkDecls('not-yet-standard-property-a', function (decl) {
css.insertAfter(rule, '.ie ' + rule.selector + '{ standard-property-a: '+ decl.value +' }');
});
rule.walkDecls('not-yet-standard-property-b', function (decl) {
css.insertAfter(rule, '.ie ' + rule.selector + '{ standard-property-b: '+ decl.value +' }');
});
rule.walkDecls('not-yet-standard-property-c', function (decl) {
css.insertAfter(rule, '.ie ' + rule.selector + '{ standard-property-c: '+ decl.value +' }');
});
});
}
但输出并不理想......
.selector {
color: red;
not-yet-standard-property-a: 10px;
not-yet-standard-property-b: 20px;
not-yet-standard-property-c: 53px;
}
.ie .selector {
standard-property-c: 53px;
}
.ie .selector {
standard-property-b: 20px;
}
.ie .selector {
standard-property-a: 10px;
}
理想情况下,新规则只会在遍历整个规则后添加一次,但PostCSS似乎不允许在walkRules函数内部使用条件,因此我不确定如何阻止它为每个规则创建新规则它看到的规则。
我已经链接到上面代码的演示。对于更好的架构的任何建议都会非常感激,就像我之前说过的那样,我对此很新。谢谢!
修改:已解决。非常感谢Andrey Sitnik!我将他的答案标记为正确,因为其中的概念是我所需要的。对于那些寻找完整解决方案的人,请参阅以下代码(和演示!):
function isNotYetStandardProp (propName) {
if (propName.indexOf('not-yet-standard-property-') > -1) {
return true;
}
else {
return false;
}
}
function transformPropName (propName) {
return propName.replace("not-yet-", "");
}
var skipNext = false;
var convertedProps = [];
var newRule;
var newNode;
return function (css) {
css.walkRules(function(rule) {
// The skipNext flag is used to prevent walkRules from walking onto any
// newly created rules and recursively creating new rules based on the
// newly added rule.
if (!skipNext) {
// Reset to remove values from last loop
convertedProps = [];
newRule = null;
newNode = null;
// Search through nodes of current rule and build up array
// containing each property that needs to change.
rule.nodes.filter(function (node) {
if ((node.type === 'decl') && isNotYetStandardProp(node.prop)) {
newNode = node.clone();
newNode.prop = transformPropName(node.prop);
convertedProps.push(newNode);
}
});
// If there were properties to convert in this rule create a new
// rule to put them in.
if (convertedProps.length > 0) {
newRule = rule.cloneAfter({ selector: '.ie ' + rule.selector });
newRule.removeAll().append(convertedProps);
skipNext = true;
}
}
else {
// We only want to skipNext once.
skipNext = false;
}
})
}
答案 0 :(得分:1)
您walkDecls
内部walkRules
不需要rule.nodes
,只需使用css.walkRules(rule => {
const nonStandard = rule.nodes.filter(node => {
return if node.type === 'decl' && checkPropName(node.prop);
});
if ( nonStandard.length > 0 ) {
const clone = rule.cloneAfter({ selector: '.ie ' + rule.selector });
clone.append(nonStandard);
}
})
:
locationInView