建立一个字符串,这取决于可变数量的参数
Building of a string, which depends on variable number of parameters
我的问题是:如何在 Less 中构建一个字符串,这取决于可变数量的参数。例如,我想做一个 mixin,它可以帮助我编写 @font-face
CSS 规则。所以我需要为我的字体的任意数量的格式(.eot、.ttf、.oft、.woff、.woff2、.svg)构建 src:...
字体 属性。这是我处理列表中所有字体格式的 Less 循环:
// @some-types - it is my font formats list, just smth. like 'otf', 'eot',...
// @old-src-value - it is string with src for my font from previous loop
// @counter - it is my loop counter
.make-font-src(@some-types; @old-src-value; @counter) when (@counter <= length(@some-types)) {
// Here we get next font format from @some-types
@font-type: extract(@some-types, @counter);
// Used for building 'format("opentype")' - like part of src value string
.get-font-format(@font-type);
// Building a part of src value string for this iteration
@src-value: e('@{old-src-value}, url("@{font-path}@{font-filename}.@{font-type}") format("@{font-format}")');
// Recursive call of this mixin for looping
.make-font-src(@some-types; @src-value; (@counter + 1));
}
所以我被困在如何获取完整的 src 值字符串,当所有字体格式都将在循环中处理时?另请参考this codepen demo.
如我的评论所述,这不会导致递归定义错误,因为您已将值分配给不同的变量然后使用它。但是,Less 似乎在循环的第一次迭代完成后立即处理 属性-value 设置行。您可以通过将第一次迭代本身的 counter
值更改为 2 或更多来验证这一点。
一个解决方案(在我看来是解决问题的更好方法)是使用 property merging with comma 功能并直接设置 属性-value 对,如下面的代码片段所示:
.make-font-src(@some-types; @counter) when (@counter <= length(@some-types)) {
@font-path: 'some/test/path/';
@font-filename: 'Arial';
@font-type: extract(@some-types, @counter);
src+: e('url("@{font-path}@{font-filename}.@{font-type}") format("@{font-type}")');
.make-font-src(@some-types; (@counter + 1));
}
div.test {
.make-font-src('eot', 'woff', 'svg'; 1);
}
这在编译时会产生以下输出:
div.test {
src: url("some/test/path/Arial.eot") format("eot"),
url("some/test/path/Arial.woff") format("woff"),
url("some/test/path/Arial.svg") format("svg");
}
最后,我找到了自己的解决方案:如果我们添加带有保护的特殊 'getter' 混入,它会在循环的最后一次迭代中触发,我们可以从循环混入中获得完整的 src 值。
.getter(@cond; @list) when (@cond = length(@list)) {
@font-src-full: @src-value;
}
这是一个fiddle with demo
我的问题是:如何在 Less 中构建一个字符串,这取决于可变数量的参数。例如,我想做一个 mixin,它可以帮助我编写 @font-face
CSS 规则。所以我需要为我的字体的任意数量的格式(.eot、.ttf、.oft、.woff、.woff2、.svg)构建 src:...
字体 属性。这是我处理列表中所有字体格式的 Less 循环:
// @some-types - it is my font formats list, just smth. like 'otf', 'eot',...
// @old-src-value - it is string with src for my font from previous loop
// @counter - it is my loop counter
.make-font-src(@some-types; @old-src-value; @counter) when (@counter <= length(@some-types)) {
// Here we get next font format from @some-types
@font-type: extract(@some-types, @counter);
// Used for building 'format("opentype")' - like part of src value string
.get-font-format(@font-type);
// Building a part of src value string for this iteration
@src-value: e('@{old-src-value}, url("@{font-path}@{font-filename}.@{font-type}") format("@{font-format}")');
// Recursive call of this mixin for looping
.make-font-src(@some-types; @src-value; (@counter + 1));
}
所以我被困在如何获取完整的 src 值字符串,当所有字体格式都将在循环中处理时?另请参考this codepen demo.
如我的评论所述,这不会导致递归定义错误,因为您已将值分配给不同的变量然后使用它。但是,Less 似乎在循环的第一次迭代完成后立即处理 属性-value 设置行。您可以通过将第一次迭代本身的 counter
值更改为 2 或更多来验证这一点。
一个解决方案(在我看来是解决问题的更好方法)是使用 property merging with comma 功能并直接设置 属性-value 对,如下面的代码片段所示:
.make-font-src(@some-types; @counter) when (@counter <= length(@some-types)) {
@font-path: 'some/test/path/';
@font-filename: 'Arial';
@font-type: extract(@some-types, @counter);
src+: e('url("@{font-path}@{font-filename}.@{font-type}") format("@{font-type}")');
.make-font-src(@some-types; (@counter + 1));
}
div.test {
.make-font-src('eot', 'woff', 'svg'; 1);
}
这在编译时会产生以下输出:
div.test {
src: url("some/test/path/Arial.eot") format("eot"),
url("some/test/path/Arial.woff") format("woff"),
url("some/test/path/Arial.svg") format("svg");
}
最后,我找到了自己的解决方案:如果我们添加带有保护的特殊 'getter' 混入,它会在循环的最后一次迭代中触发,我们可以从循环混入中获得完整的 src 值。
.getter(@cond; @list) when (@cond = length(@list)) {
@font-src-full: @src-value;
}
这是一个fiddle with demo