9、类名操作
发布在avalon学习教程2014年9月2日view:10981
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

ms-class是avalon用得最多的几个绑定之一,也正因为如此其功能一直在扩充中。根据时期的不同,分为旧风格与新风格两种。

旧风格是指ms-class-xxx=”expr”,*ms-class-aaa-bbb=”expr”*。正如第三节《绑定属性与扫描机制》所讲,一个绑定属性分成三部分,第一部分是ms,第二部分是class,第三部分是第二个-之后的所有字符串,它们被称之为param。上面的xxx与aaa-bbb都是我们要处理里的类名。等号后面的expr是一个表达式,根据它们的真假值决定是添加或移除。不过旧风格的缺点非常明显

  1. 每个ms-class只能控制一个类名,如果有N个类名其实都是由同一个绑定属性控制的,也不得分开写。
  2. ms-class后面只能接受全部是小写的类名,因为在HTML 规范中,属性名都只能是小写,你就算大写了,它也会转换为小写 。
  3. 有些类名,我们想动态生成出来。

因此有了新风格一说。现在不推荐使用旧风格了,不过avalon还是非常有节操地继续支持它。

<!DOCTYPE html>
<html>
    <head>
        <title>旧风格</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <script src="avalon.js"> </script>
        <script>
            var model = avalon.define({
                $id: "ms-class",
                toggle: true,
                click: function(e) {
                    model.toggle = !model.toggle
                }
            })
        </script>
        <style>
            .test{
                width:100px;
                height:100px;
                border:1px solid red;
                color:red;
                -webkit-user-select: none;  /* Chrome all / Safari all */
                -moz-user-select: none;     /* Firefox all */
                -ms-user-select: none;      /* IE 10+ */
                -o-user-select: none;
                user-select: none;          
            }
            .aaa{
                color:blue;
                border:1px solid blue;
            }
        </style>
    </head>
    <body ms-controller="ms-class">
        <div class="test" ms-class-aaa="toggle" ms-click="click">点我</div>
    </body>
</html>

enter image description here

新风格的格式为ms-class=”class:expr”。其中ms-class也可以带第三个参数(因为属性名不能重要,因此需要加一点“杂质”骗过浏览器),但它只能是数值,根据它们的大小决定执行顺序(也见第三节的扫描机制部分),如ms-class-1=”aaa”,ms-class-2=”bbb”。新风格的属性值由冒号拆分两部分,第一部分是类名,类名中可以使用插值表达式(如ms-class=”width{{w}}: isOk”),第二部分是可选,不写(不写时冒号也不用写了)就默认是添加操作,写时就根据其计算结果决定是添加还是移除(如 者ms-class=”red:1+1”)。

<!DOCTYPE html>
<html>
    <head>
        <title>新风格</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <script src="avalon.js"></script>
        <script>
            var model = avalon.define({
                $id: "ms-class",
                toggle: true,
                click: function(e) {
                    model.toggle = !model.toggle
                }
            })
        </script>
        <style>
            .test{
                width:100px;
                height:100px;
                border:1px solid red;
                color:red;
                -webkit-user-select: none;  /* Chrome all / Safari all */
                -moz-user-select: none;     /* Firefox all */
                -ms-user-select: none;      /* IE 10+ */
                -o-user-select: none;
                user-select: none;          
            }
            .aaa{
                color:blue;
                border:1px solid blue;
            }
        </style>
    </head>
    <body ms-controller="ms-class">
        <div class="test" ms-class="aaa:toggle" ms-click="click">点我</div>
        <div  ms-class="aaa"  ms-class-1="bbb"  ms-class-2="ccc"> 它的名类是aaa bbb ccc   </div>
        <div  ms-class-2="aaa" ms-class="bbb"  ms-class-1="ccc" >  它的名类是bbb ccc aaa   </div>
        <div  ms-class="bbb"  ms-class-1="aaa"  ms-class-2="ccc">  它的名类是bbb aaa ccc   </div>
        <div  ms-class="xxx yyy zzz" >  它的名类是xxx yyy zzz   </div>
        <div  ms-class="XXX YYY ZZZ:true" >  它的名类是XXX YYY ZZZ    </div>

    </body>
</html>

enter image description here

此外还有两个绑定,ms-active、 ms-hover。它们分别是用来摸拟:active, :hover效果,用法与ms-class一样,都分新旧风格。ms-active只在点击的那一瞬间有效果,ms-hover只在掠过时有效果,失去焦点或离开目标元素就会移除刚才添加的类名。

<!DOCTYPE html>
<html>
    <head>
        <title>ms-class</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="avalon.js"></script>
        <style>
            .ms-class div{
                display:inline-block;
                width:200px;
                height:100px;
                border: 1px solid  black;
            }
            .active{
                background: black;
                color: white;
            }
            .bgRed {
                background:palegoldenrod;
            }
            .hover{
                background: red;
                color: white;
            }
        </style>
        <script type="text/javascript">
            var model = avalon.define({
                $id: "test",
                w: 500,
                h: 200,
                bottom: true,
                num: "00",
                className: "点我",
                changeClassName: function() {
                    model.num = (100 * Math.random()).toFixed(0);
                    model.className = this.className
                }
            })
        </script>
    </head>
    <body ms-controller="test" class="ms-class">
        <div ms-active="active" >测试:active</div>
        <div ms-hover="hover" >测试:hover</div>
        <div ms-class="bgRed width{{w}} height{{h}}" ms-css-width="h">
            类名通过插值表达式生成<br/>
            {{w}} * {{h}}<br/>
            <input data-duplex-event="change" ms-duplex="h">
        </div>
        <p><button type="button" ms-class="test{{num}}" ms-click="changeClassName">{{className}}</button></p>
    </body>
</html>

enter image description here

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <script src="avalon.js"></script>
        <script>
            var model = avalon.define({
                $id: "test",
                color: "red",
                toggle: true,
                changeToggle: function() {
                    model.toggle = !model.toggle
                },
                switchColor: function() {
                    model.color = model.color === "red" ? "blue" : "red"
                }
            })
        </script>
        <style>
            .ms-class-test{
                background:green;
                width:300px;
                height:100px;
            }
            .c-red{
                background: red;
            }
            .c-blue{
                background: blue;
            }
        </style>
    </head>
    <body ms-controller="test">
        <div class="ms-class-test" ms-hover="c-{{color}}:toggle"> </div>
        <button ms-click="switchColor"> 点我改变类名</button> <button ms-click="changeToggle"> 点我改变toggle</button>
    </body>
</html>

enter image description here

ms-class、 ms-hover、 ms-active涵盖了所有与类名相应的需求,并且使用上比jQuery还简单。最后看一下用它实现斑马线的效果吧。

<!DOCTYPE html>
<html>
    <head>
        <title>ms-class</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <script src="avalon.js"></script>
        <script>
            avalon.define({
                $id: "test",
                array: avalon.range(0, 14)
            })
        </script>
        <style>
            .zebra-table{
                border-collapse: collapse;
                width:400px;
                border:1px solid black;
            }
            .zebra-table td{
                border:1px solid black;
                text-indent: 1em;
            }
            .zebra-table .even td{
                background:black;
                color:white;
            }
             .zebra-table .hover td{
                color: red;
                font-weight: bolder;
            }
        </style>
    </head>
    <body ms-controller="test" >
        <table class="zebra-table">
            <tr ms-repeat="array" ms-hover="hover" ms-class="even: $index % 2 == 0"><td>{{$index}}</td><td>{{ new Date - 0 | date("yyyy-MM-dd")}}</td></tr>
        </table>
    </body>
</html>

enter image description here

评论
发表评论
3年前

ms-class="active: fun();" fun(){ //一些逻辑,会根据一个[状态]返回 true 或 false }

尝试了下这样是可以正常循环的,第一次也会正常显示.但中间如果 [状态] 动态变更了,影响了对应fun返回的true或false,这时就不变了,除非重新repeat. 有没办法可以手动触发重新repeat , 获取最新的 fun() 返回的结果,从而达到动态加active这个class?

目前用了一个比较笨的方法,就是将repeat 的 VM.data.reverse().reverse() 反转2次后才会更新.

3年前

ms-class="active: fun();" fun(){ //一些逻辑,会根据一个[状态]返回 true 或 false }

尝试了下这样是可以正常循环的,第一次也会正常显示.但中间如果 [状态] 动态变更了,影响了对应fun返回的true或false,这时就不变了,除非重新repeat. 有没办法可以手动触发重新repeat , 获取最新的 fun() 返回的结果,从而达到动态加active这个class?

目前用了一个比较笨的方法,就是将repeat 的 VM.data.reverse().reverse() 反转2次后才会更新.

3年前
添加了一枚【评注】:此处的true是只控制zzz类名还是能够同时控制xxx,yyy,zzz三个类名?
3年前
添加了一枚【评注】:新风格怎么实现一个ms-class控制多个类名呢?
3年前
添加了一枚【评注】:不能重复吧?
4年前
添加了一枚【评注】:应该是不能重复吧
4年前

支持插值表达式了。。赞

WRITTEN BY
司徒正美
穿梭于二次元与二进制间的魔法师( ̄(工) ̄) 凸ส้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้้
TA的新浪微博
PUBLISHED IN
avalon学习教程

从零开始学习到掌握当前国内最强大的MVVM框架avalon

我的收藏