• 使用avalon 实现一个序列号功能


    avalon“操作数据即操作DOM”的能力,让我们可以专致于业务,写出更专业,更优雅,更易维护的代码来。现在让我们看看如何实现一个序列号输入功能。它的需求以下:

    • 每输入4个字符就跳到下一个输入框。
    • 不能输入超过4个字符。
    • 支持复制贴粘功能,每4个字符自动对位到相应的输入框。

    先给出代码:

    
    <!DOCTYPE html>
    <html>
        <head>
            <title></title>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            <script src="avalon.js"></script>
            <style>
                input:focus{
                    border: 1px solid #a9ea00;
                    background:#f0f0f0;
                }
            </style>
            <script>
                var model = avalon.define("xxx", function(vm) {
                    vm.seriesNumber = [{value: ""}, {value: ""}, {value: ""}, {value: ""}]
                    vm.focusIndex = NaN
                    //获得焦点,实现输入框中的跳转操作
                    vm.focus = function(a, b) {
                        var el = this;
                        if (a === avalon(el).data("index")) {
                            setTimeout(function() {
                                el.focus()
                                el.select();
                            }, 0);
                        }
                    }
                    vm._focus = function() {
                        model.$unwatch()
                        model.focusIndex = avalon(this).data("index")
                        model.$watch()
                    }
    
                    //通过贴粘实现智能输入
                    vm.paste = function(e) {
                        var index = avalon(this).data("index")
                        var text = ""
                        if (e.clipboardData) {
                            avalon.log("w3c")
                            text = e.clipboardData.getData("text/plain");
                        } else if (window.clipboardData) {
                            avalon.log("ie")
                            text = clipboardData.getData("Text")
                        }
                        var array = text.match(/w{4}/g) || []
                        for (var i = 0; i < array.length; i++) {
                            var el = model.seriesNumber[index + i]
                            if (el) {
                                el.value = array[i]
                            }
                        }
                        var last = Math.min(index + i, 3)
                        setTimeout(function() {
                            model.focusIndex = last
                        }, 0)
    
                    }
    
                })
                //绑定$watch,实现输入字数限制与智能跳转
                model.seriesNumber.forEach(function(el, index) {
                    el.$watch("value", function(a, b) {
                        if (a.length >= 4) {
                            model.focusIndex = index + 1 //跳转
                            el.value = a.slice(0, 4)
                        }
                    })
                })
                //刚开始时聚焦到第一个输入框中
                avalon.ready(function() {
                    model.focusIndex = 0
                })
    
    
            </script>
        </head>
        <body>
            <div ms-controller="xxx" ms-each-el="seriesNumber">
                <input ms-duplex="el.value" ms-on-paste="paste" ms-focus="_focus" ms-bind="focusIndex: focus" ms-data-index="$index">
            </div>
            <h2>1234aaaabbbb6789</h2>
        </body>
    </html>
    
    

    首先,我们要监听一个input里面的内容变化,马上能想到用ms-duplex,该绑定能逐字符地监听变化。但由于存在多个INPUT,为了方便循环处理,我们用到一个数组。但数组VM中只能监听它的长度变化。因此整成对象数组,然后监听这些对象的某个字符串属性就行了。

    这个value值的变动,我们可以绑定$watch回调,当输入值超过4个字符串时,进行跳转操作。

                  el.$watch("value", function(a, b) {
                        if (a.length >= 4) {
                            model.focusIndex = index + 1 //跳转
                            el.value = a.slice(0, 4)
                        }
                    })
    

    如果实现跳转操作呢,我们使用另一个新属性focusIndex 来监听,当它变化时,我们再调用一个跳转方法。而这个跳转方法需要得到元素节点。这唯有万能绑定ms-bind 能干这事。

    ms-bind="vmProp:vmCallback"

    vmCallback的this指向被绑定元素,并传入此绑定属性的前后两个值。vmProp的值每次变动都会调用vmCallback。

    贴粘时,我们需要用到paste事件,但avalon默认没此绑定,需要用ms-on传入事件名,这里面做些兼容处理,逐一修改seriesNumber 数组对象的value 值就行了。

    例子

    1234aaaabbbb6789

    整个流程简单利落,除了跳转时我们用到一些DOM方法,其他都是对数据的操作。这与以往jQuery, Prototype.js, YUI的实现思路完全不同。打个比喻,avalon带来的技术体验,如同书法与打印机的区别。jQuery好优雅,能让你精确控制每一步DOM操作,DOM操作越是复杂,如同繁体字那样纵横捭阖,越是显得jQuery游刃有余。avalon好干净,不要准备文房四宝,一张A4,一台打印机就行了,刷刷地出来你要的东西,干脆利落,没什么人情味,但效率奇高,是工业革命的先声。从历史的发展过程来看,书法这种讲究技术,渗杂着许多人个品味地艺术被整齐划一的印刷术逼到一死角,被剥夺了文化传承者的角色。jQuery这些也一样,DOM操作最快,也比不上MVVM这种印刷机般的技术,后者能不着痕迹地同步视图,里面精密的算法保证不会存在冗余无用的DOM操作。前者还存在“糟糕的书法者”问题,最好的笔砚,在某些人手里也是潦草不堪,看守打印机工作就没这问题。从势利的角度来看,就是怎么能够给资本家带来好处,怎么在相对时间内能够有更多更快, 更稳定的产出,就怎么快被采纳,人性使然。


    相关文章

    利用avalon 实现一个简单的成绩单

  • 相关阅读:
    GoGin 跨域处理
    Vue sso认证快速接入实践
    领域驱动设计(DDD):项目目录(包、模块)结构
    高绩效团队建设与管理系列课程
    VR设备产业链
    Supercell资深策划谈三大产品制作经验:游戏设计就像丛林探险,必须险中求胜
    领导力管理培训课
    博众投资:虚拟数字人概念,开辟元宇宙炒作新战场!
    FW: Flow区块链门票NFT开发实战【含源码】
    放弃学术研究,做投资大获成功
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/3306344.html
Copyright © 2020-2023  润新知