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

2021-07-20  本文已影响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;
}

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

上一篇 下一篇

猜你喜欢

热点阅读