UNPKG

cssobj

Version:

Runtime CSS manager, Turn CSS into dynamic JS module, Stylesheet CRUD (Create, Read, Update, Delete) in CSSOM, Solve common problems of CSS-in-JS, name space (local) class names

159 lines (110 loc) 3.58 kB
# Function as CSS Value In cssobj, if value type is **function**, then the function will be evaluated with signature: ```Javascript function(v){} -> string|number|object // v: object {raw, cooked, node, result} ``` The `v` param is an object that have members: - **raw** value of original js object (evaled when it's a function), don't add any plugins - **cooked** result value of `raw` + `plugins` - **node** current node of the closest object - **result** current result object of cssobj Example: ```javascript var result = cssobj( { p: {width: [100, v => console.log(v) ]} }, { plugins: [ defaultUnit('px') ] } ) // { raw: 100, cooked: '100px', node: Object, result: Object } ``` The return value: 1. If the function return `string|number`, then the prop will update to that 2. If the function return `object`, then the object will be merged into current style rule ## Example Below, when user click, `div` will get random `color` ```Javascript result = cssobj({ div:{ color: 'red' } }) element.onclick = function(){ result.obj.div.color = function() { return randomColor() //return a string } result.update() } ``` Below, when user click, `div` will get random `color`, and also a random `font-size` ```Javascript result = cssobj({ div:{ color: 'red' } }) element.onclick = function(){ result.obj.div.color = function() { return { color: randomColor(), fontSize: randomSize() + 'px' } //return a object } result.update() } ``` You can see more examples in [test cases](https://github.com/cssobj/cssobj-core/blob/91f508f2657db2cc3b6762db34cf2b2472bb4330/test/test.js#L1303) ## Function execute order Think there's many function as value in your source object, cssobj can control the function order by adding **$order** directive If we have below layout: ```html <div class="box1"></div> <div class="box2"></div> <div class="box3"></div> ``` The layout requirement: - box1 will have same width & height - box2's height is sum of box1 & 3 - box3's height is twice of box1 ```Javascript obj = { '.box1':{ $id:'box1', width:10, height: function(v) { return v.node.rawVal.width } }, '.box2':{ height: function(v) { return v.result.ref.box1.rawVal.height + v.result.ref.box3.rawVal.height } }, '.box3':{ $id:'box3', height: function(v) { return v.result.ref.box1.rawVal.width*2 } } } cssobj(obj, {plugins: [defaultUnit('px')] }) ``` Above, `v.prev` is the previous CSS value, after `defaultUnit` plugin, so it have `px` appended, `string` type `v.node.rawVal` is the value before `defaultUnit` plugin, so it will always keep as `number` type, ready for calculate But, the problem is, the default function invoke order is **from top to bottom** The execution order is `box1 -> box2 -> box3`, that way the result is wrong You can add **$order** directive (default value is **0**), to change there execution order ```Javascript { '.box1':{ $id:'box1', // default $order === 0 width:10, height: function(v) { return v.node.rawVal.width } }, '.box2':{ $order:2, height: function(v) { return v.result.ref.box1.rawVal.height + v.result.ref.box3.rawVal.height } }, '.box3':{ $id:'box3', $order:1, height: function(v) { return v.result.ref.box1.rawVal.width*2 } } } ``` Above, the execute order is `box1 ($order:0) -> box3 ($order:1) -> box2 ($order:2)` This time it's worked right. [See the DEMO here](https://cssobj.github.io/cssobj-demo/#demo5)