Less.js: 创建自定义函数

创建于 2012-02-16  ·  28评论  ·  资料来源: less/less.js

你好,

定义像这样的自定义函数会很好:

  darkfadein(<strong i="7">@color</strong>, @value) {
    return fadein(darken(<strong i="8">@color</strong>, @value));
  }

  .foo {
    color: darkfadein(#333, 10%);
  }

应编译为:

  .foo {
    color: #1a1a1a;
  }
consider closing feature request low priority

最有用的评论

我发现一个 hack :如果你声明了一个全局 js 函数,你可以稍后使用它!

<strong i="6">@fn</strong>: ~`fn = function(a) { return a; }`;

<strong i="7">@arg</strong>: 8px;

p {
    font-size: ~`fn("@{arg}")`;
}

所有28条评论

也许为了将它与混入区分开来并更接近 CSS 语法,它可能是:

@darkfadein(<strong i="6">@color</strong>, @value): fadein(darken(<strong i="7">@color</strong>, @value));

有点像一个取决于参数的变量(如果你认为它是一种函数 =)

+1 @souldreamer的语法。

但是使用@souldreamer的语法,不可能写一些
值转换为变量并再次使用它们。

可以使用这个语法:

  @darkfadein(<strong i="9">@color</strong>, @value) {
     <strong i="10">@foo</strong>: darken(<strong i="11">@color</strong>, @value);
     return: fadein(@foo);
  }

在以后的版本中可能会做这样的事情:

  @darkfadein(<strong i="15">@color</strong>, @value) {
     <strong i="16">@foo</strong>: darken(<strong i="17">@color</strong>, @value);
     for(<strong i="18">@i</strong> = 0; <strong i="19">@i</strong> < 5; @i++): {
       <strong i="20">@foo</strong>: darken(<strong i="21">@foo</strong>, @i);
     };
     return: fadein(@foo);
  }

我也有类似的需求,需要使用某种函数来返回一个值。 我认为有两种可能的解决方案。 一种解决方案是将变量语法扩展为上面概述的

@grid-width(<strong i="7">@columns</strong>, @column-width) {
    <strong i="8">@computedWidth</strong> = @columns*@column-width;
    return @computedWidth;
}
div {
    width: @grid-width(6,60);
}

第二种方法是使用mixin。 由于编译器无论如何都将 mixin 视为 JavaScript 函数,_向 mixins_ 添加return功能可能是一个简单的补救措施。 这是它的样子:

.grid-width(<strong i="13">@columns</strong>, @column-width) {
    <strong i="14">@computedWidth</strong> = @columns*@column-width;
    return @computedWidth;
}
div {
    width: .grid-width(6,60);
}

SASS 的“功能指令”提供了类似的结果,但我相信这种混合解决方案会更优雅。

问题508609也与此有关。

我认为@tylertate的第二种语法是最好的。 我接缝是最简单的,因为正如你所说的那样,less 已经将 mixin 解析为 JavaScript。

使用 mixin 会有这样的想法吗?

.grid-width(<strong i="8">@columns</strong>, @column-width) {
    <strong i="9">@computedWidth</strong> = @columns*@column-width;
    for (var i = 0; i <= 36; i++) {
      <strong i="10">@computedWidth</strong> = darken(<strong i="11">@computedWidth</strong>, i);
    }
    return @computedWidth;
}
div {
    width: .grid-width(6,60);
}

我宁愿看到类似定义的 LESS 插件语法的东西,并将类似编程的逻辑移动到 JavaScript LESS 插件。 这些建议与当前的 LESS 语法和设计不一致。

同意.. 有一个关于标记文档的错误,因为当你知道如何添加函数时它相对简单。

那么决议是什么?

我们需要记录下来。 见https://github.com/cloudhead/lesscss.org/issues/54

来自less.js的链接问题显示了如何在浏览器中向less添加函数

less = { functions: { rgbstr: function (color) {var str = color; return new(less.tree.Quoted)('"' + str + '"', str,true,1);}}};

目前没有办法将功能插入节点版本,但应该有

谢谢,我很欣赏响应和让 JavaScript 脱离 LESS 语法的立场。

然而,不强制将 mixin 的返回值与特定属性相关联似乎是一个如此清晰的用例。 任何使用网格的人都会想做@Deltachaos试图做的事情。 能够在不下降到创建插件级别的情况下实现这一点会很棒。

这是一件棘手的事情——如果你需要循环或者它是否需要存在于插件中。

但是,如果它使用特定值调用 3 个 less 函数,我同意能够在 less 中提取它以使语法干燥是有意义的 - 必须编写一个插件来提取事实是没有意义的你想在一个地方变暗 5%。

我已经重新打开,但这可能会在其他地方复制,我们会看到。

目前来自 mixins 作用域的变量都被复制到外部作用域——这是返回变量的一种方式..但它导致了可怕的问题,我想删除它。

#538 的副本

“来自 mixins 作用域的变量都被复制到外部作用域”

呃,真的吗? 是的,让我们删除这种行为。 我宁愿将变量标记为导出,或者其他一些不仅仅是自动泄漏的东西。 这对我来说不是预期的行为。 变量应该是块范围的。

是的,就像通过后门漏洞支持功能一样

我发现一个 hack :如果你声明了一个全局 js 函数,你可以稍后使用它!

<strong i="6">@fn</strong>: ~`fn = function(a) { return a; }`;

<strong i="7">@arg</strong>: 8px;

p {
    font-size: ~`fn("@{arg}")`;
}

@fabienevain刚刚发现了同样的 hack :)

@fabienevain效果很好,谢谢~ :+1:

我发现您可以通过访问 process.mainModule 从同一个 eval jail 中创建实际函数...唯一的问题是您可能必须遍历process.mainModule.children并匹配 less.js 如果该顺序由于某种原因在未来。 我不打算迭代只是盲目地相信less是第三个模块。

不幸的是,您无法访问require ,但您可以访问fs和其他已经被 less 需要的东西,这已经足够了:

<strong i="10">@anything</strong>: `(function() {
    // console.log(process.mainModule.children[0].exports); // node fs is here
    // console.log(process.mainModule.children[2].children) // children of less, more node modules!
    var less = process.mainModule.children[2].exports;

    less.functions.functionRegistry.add("firstfunc", function(a, context) {
        // console.log(a, context);
        return new less.tree.Color("00ff00");
    });

    less.functions.functionRegistry.add("secondfunc", function(a, context) {
        // console.log(a, context);
        return new less.tree.Color("ff0000");
    });
})()`;


test {
    background: firstfunc(white);
    color: secondfunc(black);
}

具有真正功能的巧妙之处在于这个context变量,它包含诸如正在处理的文件之类的多汁细节,因此您可以例如使用设置等创建自己的 svg 数据 uri 导入。

编辑我想知道如果试图将 JS 排除在外,为什么还要引入反引号。 我喜欢我的 LESS 尽可能复制和粘贴,所以插件对我不利。

我喜欢我的 LESS 尽可能复制和粘贴,所以插件对我不利。

因此,即使您在内联反引号 hack 中需要基于 node.js 的 less.js 编译器,您也假设您的代码是“复制和粘贴”,但同时又觉得如果您使用插件会出错? 哦!

@seven-phases-max 我的工具一团糟。 如果我可以控制 lessc 命令行参数,我可能会使用插件。 (或者有一个主插件来填充所有东西)但是不,我搞砸了我的环境,我在 Eclipse 工作区中有大约 100 个 WP 主题,我无法摆脱它们,因为所有构建命令等都卡在那里.

@Ciantic首先,您不需要任何特定的命令行选项来使用自定义函数插件 - 如有必要(#2479)。 次要我怀疑任何严重破坏的环境禁止您控制编译器选项(毕竟lessc “可执行文件”只是一个重定向到实际节点脚本的操作系统控制台脚本 - 因此人们可以轻松地以一种或另一种方式注入 _anything_ )。

无论哪种方式,我的评论都只是关于“复制和粘贴与插件”的广告。 而事实证明,这只是一个损坏的构建工具/链的解决方法。

@seven-phases-max 导入插件看起来正是我需要的工具! 虽然我想在我的项目中定义函数,而不是在全局注册表中,这样我就可以编辑项目中的函数,而不必担心如果我对全局函数进行更改会破坏十亿个文件。

@Ciantic

虽然我想在我的项目中定义函数,而不是在全局注册表中,这样我就可以编辑项目中的函数,而不必担心如果我对全局函数进行更改会破坏十亿个文件。

进一步阅读。我的拉取请求的初始草案采用了全局注册的简单路线,但随着获得了一些见解,我后来对其进行了改进,以进行范围本地注册。 例如

.my-mixin() {
  <strong i="10">@plugin</strong> "my-func.js";
  <strong i="11">@value</strong> : my-func();
}

不会泄漏my-func到 mixin 范围之外。 路径当然也与包含@plugin声明的文件相关,因此所有内容都被整齐地捆绑并可供第三方使用; 100% _透明地_。

这是我对这个功能的设计目标。 ^_^

less.js 需要添加自定义颜色组合
提交代码时出现问题
它支持但需要less.js

我发现一个 hack :如果你声明了一个全局 js 函数,你可以稍后使用它!

<strong i="7">@fn</strong>: ~`fn = function(a) { return a; }`;

<strong i="8">@arg</strong>: 8px;

p {
    font-size: ~`fn("@{arg}")`;
}

@fabienevain如何在@fn使用较少的函数? 比如hsvsaturationunit等等。

@hiyangguo

你不应该使用内联 JS 表达式,句号。
以适当的方式构建和注册自定义函数。
阅读文档。 这一切都在那里: http ://lesscss.org/features/#plugin -atrules-feature

@rjgotten好的,非常感谢。

此页面是否有帮助?
0 / 5 - 0 等级