Less.js: Criação de funções personalizadas

Criado em 16 fev. 2012  ·  28Comentários  ·  Fonte: less/less.js

Oi,

Seria bom definir funções Custome como:

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

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

deve ser compilado para:

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

Comentários muito úteis

Eu acho um hack: se você declarar uma função js global, você pode usá-la mais tarde!

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

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

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

Todos 28 comentários

Talvez para diferenciá-lo de um mix-in e ficar mais próximo da sintaxe CSS, poderia ser:

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

Como uma variável que depende de parâmetros (que se você pensar é uma espécie de função =)

+1 para a sintaxe de @souldreamer .

Mas com a sintaxe de @souldreamer não seria possível escrever alguns
valores em variáveis ​​e use-os novamente.

pode usar esta sintaxe:

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

talvez seja possível em versões posteriores fazer algo assim:

  @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);
  }

Tenho uma necessidade semelhante de usar algum tipo de função para retornar um valor. Acho que existem duas soluções possíveis. Uma solução seria estender a sintaxe da variável como @Deltachaos descrito acima, que é essencialmente:

@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);
}

Uma segunda abordagem seria usar mixins. Visto que o compilador trata os mixins como funções JavaScript de qualquer maneira, _adicionar um recurso return aos mixins_ provavelmente seria um remédio simples. Seria assim:

.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);
}

As "diretivas funcionais" do SASS fornecem um resultado semelhante, embora eu acredite que essa solução de mixin seria muito mais elegante.

Os problemas 508 e 609 também estão relacionados a isso.

Acho que a segunda sintaxe de @tylertate seria a melhor. Parece ser o mais fácil porque, como você disse menos, já analisa mixins como JavaScript.

Será que algo assim seria possível com mixins?

.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);
}

Prefiro ver algo como uma sintaxe de plug-in LESS definida e mover a lógica de programação para um plug-in LESS de JavaScript. Essas sugestões são inconsistentes com a sintaxe e o design atuais do LESS.

Concordo .. há um bug nessa documentação marcada, pois é relativamente simples adicionar funções quando você sabe como.

Então, qual foi a resolução?

Precisamos documentar isso. consulte https://github.com/cloudhead/lesscss.org/issues/54

e o problema vinculado de less.js mostra como você pode adicionar uma função a less no navegador

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

no momento, não há como inserir funções na versão do nó, mas deve haver

Obrigado, agradeço a resposta e a posição para retirar o JavaScript da sintaxe do LESS.

No entanto, não ser forçado a associar o valor de retorno de um mixin a uma propriedade específica parece um caso de uso claro. Qualquer um que usa uma grade vai querer fazer o que @Deltachaos estava tentando fazer. Seria ótimo poder fazer isso sem cair no nível de criação de um plugin.

É uma coisa complicada - se você precisa de loops ou se precisa de um plugin.

No entanto, se estiver chamando 3 funções a menos com valores específicos, concordo que faz sentido ser capaz de extrair menos isso dentro para tornar a sintaxe DRY - não faz sentido ter que escrever um plugin para extrair o fato de que você deseja escurecer 5% em um só lugar.

Eu reabri, mas isso pode estar duplicado em outro lugar, veremos.

no momento, as variáveis ​​de um escopo mixins são copiadas para o escopo externo - que é uma forma de retornar variáveis ​​.. mas está causando problemas horríveis e eu quero removê-lo.

duplicado de # 538

"variáveis ​​de um escopo mixins são todas copiadas para o escopo externo"

Ugh, sério? Sim, vamos remover esse comportamento. Prefiro que as variáveis ​​sejam marcadas para exportação ou alguma outra coisa do que apenas vazamento automático. Esse não é um comportamento esperado para mim. As variáveis ​​devem ter escopo de bloco.

sim, é como apoiar funções por meio de um bug da porta dos fundos

Eu acho um hack: se você declarar uma função js global, você pode usá-la mais tarde!

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

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

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

@fabienevain encontrou o mesmo hack agora mesmo :)

@fabienevain Funcionou bem, obrigado ~: +1:

Descobri que você pode criar funções reais da mesma prisão de avaliação acessando process.mainModule ... O único problema é que você pode ter que iterar mais de process.mainModule.children e corresponder a less.js se a ordem por algum motivo mudar em futuro. Eu planejo não repetir, apenas confiar cegamente menos é o terceiro módulo.

Infelizmente você não pode acessar require , mas pode acessar fs e outros que já são necessários por menos, o que é bastante:

<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);
}

Uma coisa legal sobre ter uma função real é esta variável context , que contém detalhes interessantes como o arquivo sendo processado para que você possa, por exemplo, criar sua própria importação de uri de dados svg com configurações etc.

Editar Eu me pergunto por que crases são introduzidos se JS é tentado a ser mantido fora. Gosto do meu MENOS o mais copiável e colável possível, então os plug-ins não são bons para mim.

Gosto do meu MENOS o mais copiável e colável possível, então os plug-ins não são bons para mim.

Então você assume que seu código _é_ "copiado e colável" mesmo se você precisar do compilador less.js baseado em node.js em seus hacks de backtick embutidos, mas ao mesmo tempo sente que deu errado se você usasse plug-ins? Doh!

@ seven-phase-max minhas ferramentas estão bem bagunçadas. Se eu pudesse controlar os argumentos de linha de comando do lessc, provavelmente usaria plug-ins. (Ou ter um plugin mestre onde eu enfio tudo) Mas não, eu estraguei meu ambiente e tenho ~ 100 temas WP no espaço de trabalho do Eclipse dos quais não consigo me livrar porque todos os comandos de construção etc. estão presos lá .

@Ciantic Em primeiro lugar, você não precisa de nenhuma opção de linha de comando em particular para usar um plugin de funções personalizadas - se necessário (# 2479). Secundário, eu duvido que qualquer ambiente profundamente confuso proíba você de controlar as opções do compilador (afinal lessc "executável" é apenas um script de console do sistema operacional redirecionando para o script de nó real - então alguém pode facilmente injetar _qualquer_coisa_ lá de uma forma ou de outra).

De qualquer forma, meu comentário foi apenas sobre "copiar e colar vs. plug-ins" adv. enquanto acaba sendo apenas uma solução alternativa para uma corrente / ferramentas de construção quebradas.

O plugin de importação @ seven-phase-max parece exatamente a ferramenta que eu preciso! Embora eu gostaria de definir as funções dentro do meu projeto, não no registro global, desta forma posso editar as funções dentro do projeto e não me preocupar em quebrar bilhões de arquivos a menos se eu fizer uma alteração na função global.

@Ciantic

Embora eu gostaria de definir as funções dentro do meu projeto, não no registro global, desta forma posso editar as funções dentro do projeto e não me preocupar em quebrar bilhões de arquivos a menos se eu fizer uma alteração na função global.

Leia mais. O rascunho inicial da minha solicitação pull foi o caminho mais fácil do registro global, mas com alguns insights adquiridos, eu o refinei mais tarde para fazer o registro local do escopo. Por exemplo

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

não vazará my-func fora do escopo do mixin. É claro que os caminhos também são relativos ao arquivo que contém a declaração @plugin , portanto, tudo é agrupado ordenadamente e pode ser enviado para consumo por terceiros; 100% _transparantemente_.

Esse era meu objetivo de design para este recurso. ^ _ ^

less.js é necessário para adicionar combinações de cores personalizadas
problema ocorre durante a confirmação do código
é compatível, mas precisa de less.js

Eu acho um hack: se você declarar uma função js global, você pode usá-la mais tarde!

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

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

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

@fabienevain Como posso usar menos funções em @fn ? Como hsvsaturationunit e assim por diante .Thx.

@hiyangguo

Você não deve usar expressões JS embutidas, ponto final.
Crie e registre funções personalizadas da maneira apropriada.
Leia a documentação. Está tudo lá: http://lesscss.org/features/#plugin -atrules-feature

@rjgotten OK, muito obrigado.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

pknepper picture pknepper  ·  3Comentários

BrianMulhall picture BrianMulhall  ·  4Comentários

heavyk picture heavyk  ·  3Comentários

chricken picture chricken  ·  6Comentários

joe223 picture joe223  ·  4Comentários