所以我想少构建我的网格。 我使用 less 页面 ( http://lesscss.org/features/#loops-feature ) 中描述的 columns 方法。但是当我运行它时出现错误。
Error: Maximum call stack size exceeded in file /assets/less/grid.less line no. 54
第 54 行是我启动循环的地方 .loop(@grids, (@grids + 1));
如果我删除 mixin 中的 .generate-offset(@n, @tag, (@i + 1));
,我会收到另一个错误。
Error: Cannot read property 'denominator' of undefined in file/assets/less/grid.less line no. 54
但是,当我手动运行 mixin 时,我的工作就像一个魅力。 例如
.generate-columns(2, xs);
.generate-offset(2, xs);
如果我在没有 .generate-columns
和 .generate-offset
mixin 的情况下运行 .loop
mixin,它也能正常工作并运行 3时间与预期一致(由于 3 个断点)。
您知道为什么在组合两者时会出现这些错误吗?
@prefixes: 'sm', 'md', 'lg';
@breakpoints: '0', '100rem', '140rem';
@columns: '2','6','12';
.generate-offset(@n, @tag, @i: 1) when (@i < @n) {
.offset--@{tag}-@{i} {
margin-left: (@i * 100% / @n);
}
.generate-offset(@n, @tag, (@i + 1));
}
// Grid loops
.loop(@index, @count) when (@index > 0){
// extract variables
@current: (@count - @index);
@prefix: e(extract(@prefixes, @current));
@breakpoint: e(extract(@breakpoints, @current));
@column: e(extract(@columns, @current));
@media (min-width: @breakpoint) {
.generate-columns(@column, @prefix);
.generate-offset(@column, @prefix);
}
.loop ((@index - 1), @count);
}
// run
@grids: length(@breakpoints);
.loop(@grids, (@grids + 1));
解决方案:
以防万一有人遇到同样的问题,我的最终代码现在如下所示。
@prefixes: sm, md, lg;
@breakpoints: 0, 100rem, 140rem;
@columns: 2,6,12;
// ********************
// Column Mixin
//
.generate-columns(@n, @tag, @i: 1) when (@i =< @n) {
.column--@{tag}-@{i} {
flex: 0 0 (@i * 100% / @n);
}
.generate-columns(@n, @tag, (@i + 1));
}
// Offset Mixin
//
.generate-offset(@col, @tag, @i: 1) when (@i < @col) {
.offset--@{tag}-@{i} {
margin-left: (@i * 100% / @col);
}
.generate-offset(@col, @tag, (@i + 1));
}
// Make grid
//
.make-grid(@breakpoint, @cols, @pref) {
& when( @breakpoint > 0 ){
@media(min-width: @breakpoint) {
.generate-columns(@cols, @pref);
.generate-offset(@cols, @pref);
}
}
& when( @breakpoint = 0 ){
.generate-columns(@cols, @pref);
.generate-offset(@cols, @pref);
}
}
// Run make-grid for every breakpoint
//
.loop(@index) when (@index > 0){
// run loop first to change order
.loop ((@index - 1));
.make-grid(
extract(@breakpoints, @index),
extract(@columns, @index),
extract(@prefixes, @index)
);
}
.loop(length(@breakpoints));
最佳答案
您的情况的问题是因为 e()
(或 ~()
)函数的输出始终是一个字符串,您不能使用它来执行数学运算或比较等。您可以通过在您的代码中添加以下行来验证这一点: @media
查询(并注释掉 mixin 调用)。
columnIsNumber: isnumber(@column);
/* with your current method this will always return false */
要解决此问题,您应该避免对要执行数学运算的任何变量使用 e()
函数。例如,您可以将 mixin 更改为如下所示(有关所做的更改,请参阅内联注释):
@prefixes: 'sm', 'md', 'lg';
@breakpoints: '0', '100rem', '140rem';
@columns: 2, 6, 12; /* note the exclusion of quotes */
.generate-offset(@n, @tag, @i: 1) when (@i < @n) {
.offset--@{tag}-@{i} {
margin-left: (@i * 100% / @n);
}
.generate-offset(@n, @tag, (@i + 1));
}
// Grid loops
.loop(@index, @count) when (@index > 0){
// extract variables
@current: (@count - @index);
@breakpoint: e(extract(@breakpoints, @current));
@column: extract(@columns, @current); /* avoid using e() */
@prefix: e(extract(@prefixes, @current));
@media (min-width: @breakpoint) {
.generate-columns(@column, @prefix);
/*columnIsNumber: isnumber(@column);*/
.generate-offset(@column, @prefix);
}
.loop ((@index - 1), @count);
}
// run
@grids: length(@breakpoints);
.loop(@grids, (@grids + 1));
当然,您可以使用自己的代码(在变量声明中使用引号,在 mixin 中使用 e()
)使用一些 JS 计算来完成此操作。但我不会推荐这种方法,因为在我看来它只会增加复杂性。
@media (min-width: @breakpoint) {
.generate-columns(@column, @prefix);
@col: `function(){return @{column}}()`; /* JS evaluation */
/*columnIsNumber: isnumber(@col);*/
.generate-offset(@col, @prefix);
}
或
@media (min-width: @breakpoint) {
.generate-columns(@column, @prefix);
@col: `function(){return parseInt(@{column},10)}()`; /* JS evaluation */
/*columnIsNumber: isnumber(@col);*/
.generate-offset(@col, @prefix);
}
关于css - 少CSS : Maximum call stack size with loop in loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28257472/