使用avalon 實現一個序列號功能

avalon「操做數據即操做DOM」的能力,讓咱們能夠專致於業務,寫出更專業,更優雅,更易維護的代碼來。如今讓咱們看看如何實現一個序列號輸入功能。它的需求如下:html

  • 每輸入4個字符就跳到下一個輸入框。
  • 不能輸入超過4個字符。
  • 支持複製貼粘功能,每4個字符自動對位到相應的輸入框。

先給出代碼:git


<!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中只能監聽它的長度變化。所以整成對象數組,而後監聽這些對象的某個字符串屬性就好了。github

這個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。ruby

貼粘時,咱們須要用到paste事件,但avalon默認沒此綁定,須要用ms-on傳入事件名,這裏面作些兼容處理,逐一修改seriesNumber 數組對象的value 值就好了。mvvm

例子

1234aaaabbbb6789

整個流程簡單利落,除了跳轉時咱們用到一些DOM方法,其餘都是對數據的操做。這與以往jQuery, Prototype.js, YUI的實現思路徹底不一樣。打個比喻,avalon帶來的技術體驗,如同書法與打印機的區別。jQuery好優雅,能讓你精確控制每一步DOM操做,DOM操做越是複雜,如同繁體字那樣縱橫捭闔,越是顯得jQuery遊刃有餘。avalon好乾淨,不要準備文房四寶,一張A4,一臺打印機就好了,刷刷地出來你要的東西,乾脆利落,沒什麼人情味,但效率奇高,是工業革命的先聲。從歷史的發展過程來看,書法這種講究技術,滲雜着許多人個品味地藝術被整齊劃一的印刷術逼到一死角,被剝奪了文化傳承者的角色。jQuery這些也同樣,DOM操做最快,也比不上MVVM這種印刷機般的技術,後者能不着痕跡地同步視圖,裏面精密的算法保證不會存在冗餘無用的DOM操做。前者還存在「糟糕的書法者」問題,最好的筆硯,在某些人手裏也是潦草不堪,看守打印機工做就沒這問題。從勢利的角度來看,就是怎麼可以給資本家帶來好處,怎麼在相對時間內可以有更多更快, 更穩定的產出,就怎麼快被採納,人性使然。ui


相關文章this

利用avalon 實現一個簡單的成績單htm

相關文章
相關標籤/搜索