美文网首页
Stylus预处理器简介(七)内置方法7

Stylus预处理器简介(七)内置方法7

作者: 曲昶光 | 来源:发表于2021-07-20 09:26 被阅读0次

    实用方法

    called-from property

    ' called-from '属性包含以倒序调用当前函数的函数列表(第一项是最深的函数)。

    foo()
      bar()
    
    bar()
      baz()
    
    baz()
      return called-from
    
    foo()
    // => bar foo
    

    current-media()

    ' current-media() '函数返回当前块的' @media '规则字符串(或"如果块上面没有' @media ')。

    @media only screen and (min-width: 1024px)
      current-media()
    // => '@media (only screen and (min-width: (1024px)))'
    

    +cache(keys…)

    +cache是一个非常强大的内置函数,它允许你创建自己的“可缓存”mixins。
    一个“可缓存的mixin”在第一次调用时将其内容应用于给定的选择器,但在第二次调用时使用相同的参数@extend第一次调用的选择器。

    size($width, $height = $width)
      +cache('w' + $width)
        width: $width
      +cache('h' + $height)
        height: $height
    
    .a
      size: 10px 20px
    .b
      size: 10px 2em
    .c
      size: 1px 2em
    

    相当于

    .a,
    .b {
      width: 10px;
    }
    .a {
      height: 20px;
    }
    .b,
    .c {
      height: 2em;
    }
    .c {
      width: 1px;
    }
    

    查看选择器是如何通过所使用的属性组合在一起的。

    +prefix-classes(prefix)

    Stylus附带了一个block mixin前缀-classes,可以用来为任何给定Stylus块中的类添加前缀。例如:

    +prefix-classes('foo-')
      .bar
        width: 10px
    

    相当于

    .foo-bar {
      width: 10px;
    }
    

    lookup(name)

    允许查找作为字符串传递的名为' name '的变量的值。如果变量未定义,则返回' null '。
    当你需要动态生成一个变量的值时很有用:

    font-size-1 = 10px
    font-size-2 = 20px
    font-size-3 = 30px
    
    for i in 1..3
      .text-{i}
        font-size: lookup('font-size-' + i)
    

    相当于

    .text-1 {
      font-size: 10px;
    }
    .text-2 {
      font-size: 20px;
    }
    .text-3 {
      font-size: 30px;
    }
    

    define(name, expr[, global])

    允许使用给定的' name '创建或覆盖变量,并将其作为字符串传递到当前作用域(如果' global '为真,则为全局作用域)。
    这个BIF在你需要在变量名中插补的情况下很有用:

    prefix = 'border'
    border = { color: #000, length: 1px, style: solid }
    
    for prop, val in border
      define(prefix + '-' + prop, val)
    
    body
      border: border-length border-style border-color
    

    相当于

    body {
      border: 1px solid #000;
    }
    

    operate(op, left, right)

    对' left '和' right '执行' op '操作:

    op = '+'
    operate(op, 15, 5)
    // => 20
    

    selector()

    返回编译后的当前选择器或&如果在根级别调用。

    .foo
      selector()
    // => '.foo'
    
    .foo
      &:hover
        selector()
    // '.foo:hover'
    

    elector-exists(selector)

    如果选择器存在,返回true ..

    .foo
      color red
    
      a
        font-size 12px
    
    selector-exists('.foo') // true
    selector-exists('.foo a') // true
    selector-exists('.foo li') // false
    selector-exists('.bar') // false
    

    这个方法没有考虑到当前的上下文含义:

    .foo
      color red
    
      a
        font-size 12px
    
      selector-exists('a') // false
      selector-exists(selector() + ' a') // true
    

    opposite-position(positions)

    返回与给定的' position '相反的值。

    opposite-position(right)
    // => left
    
    opposite-position(top left)
    // => bottom right
    
    opposite-position('top' 'left')
    // => bottom right
    

    image-size(path)

    返回在path处找到的图像的' width '和' height '查找的执行方式与' @import '相同,通过' paths '设置进行更改。

    width(img)
      return image-size(img)[0]
    
    height(img)
      return image-size(img)[1]
    
    image-size('tux.png')
    // => 405px 250px
    
    image-size('tux.png')[0] == width('tux.png')
    // => true
    

    embedurl(path[, encoding])

    以url()文字的形式返回一个内联图像,并使用encoding编码。
    (可用编码:base64(默认)和utf8)。

    background: embedurl('logo.png')
    // => background: url("data:image/png;base64,…")
    
    background: embedurl('logo.svg', 'utf8')
    // => background: url("data:image/svg+xml;charset=utf-8,…")
    

    add-property(name, expr)

    将属性' name '与给定的' expr '添加到最近的块。
    例如:

    omething()
      add-property('bar', 1 2 3)
      s('bar')
    
    body
      foo: something()
    

    相当于

    body {
      bar: 1 2 3;
      foo: bar;
    }
    

    接下来,“神奇的”‘current-property’局部变量开始发挥作用。该变量自动可用于函数体,并包含具有当前属性名称和值的表达式。
    例如,如果我们使用p()检查这个局部变量,我们会得到以下结果:

    p(current-property)
    // => "foo" (foo __CALL__ bar baz)
    
    p(current-property[0])
    // => "foo"
    
    p(current-property[1])
    // => foo __CALL__ bar baz
    

    使用current-property,我们可以进一步使用我们的示例,使用新值复制属性,并使用一个条件,以确保函数只在属性值中使用。

    something(n)
      if current-property
        add-property(current-property[0], s('-webkit-something(%s)', n))
        add-property(current-property[0], s('-moz-something(%s)', n))
        s('something(%s)', n)
      else
        error('something() must be used within a property')
    
    body {
      foo: something(15px) bar;
    }
    

    相当于

    body {
      foo: -webkit-something(15px);
      foo: -moz-something(15px);
      foo: something(15px) bar;
    }
    

    如果你在上面的例子中注意到,' bar '只在初始调用时出现,因为我们返回了' something(15px) ',它在表达式中保持原位,然而其他的没有考虑表达式的其余部分。
    下面我们更健壮的解决方案定义了一个名为' replace() '的函数,它克隆表达式以防止突变,用另一个表达式替换一个表达式的字符串值,并返回克隆的表达式。然后我们继续在表达式中替换' CALL ',它表示对' something() '的循环调用。

    replace(expr, str, val)
      expr = clone(expr)
      for e, i in expr
        if str == e
          expr[i] = val
      expr
    
    something(n)
      if current-property
        val = current-property[1]
        webkit = replace(val, '__CALL__', s('-webkit-something(%s)', n))
        moz = replace(val, '__CALL__', s('-moz-something(%s)', n))
        add-property(current-property[0], webkit)
        add-property(current-property[0], moz)
        s('something(%s)', n)
      else
        error('something() must be used within a property')
    
    body
      foo: something(5px) bar baz
    

    相当于

    body {
      foo: -webkit-something(5px) bar baz;
      foo: -moz-something(5px) bar baz;
      foo: something(5px) bar baz;
    }
    

    我们的实现现在对于内部调用的属性和调用的位置都是完全透明的。
    这个强大的概念有助于厂商对函数调用的透明支持,比如渐变。

    相关文章

      网友评论

          本文标题:Stylus预处理器简介(七)内置方法7

          本文链接:https://www.haomeiwen.com/subject/caivpltx.html