js實現雙向數據綁定

<div class="app">
    <input type="demo" shawn-model="demo" spellcheck="true">
    <p shawn-text="sha"></p>
    <p shawn-text="demo"></p>

</div>
<script>
    (function(window, undefined) {

        var addEvent = (function () {
            if(window.addEventListener) {
                return function (el, type, fn) {
                    if(el && el.nodeName || el === window) {
                        el.addEventListener(type, fn, false)
                    }else if(el.length) {
                        for(var item of el) {
                            addEvent(item, type, fn);
                        }
                    }
                }
            }else {
                return function (el, type, fn) {
                    if(el && el.nodeName || el === window) {
                        el.attachEvent('on' + type, function () {
                            return fn.call(el, event);
                        })
                    }else if(el.length) {
                        for(var item of el) {
                            addEvent(item, type, fn);
                        }
                    }
                }
            }
        })();

        var Shawn = function(opt) {
            var el = document.querySelector(opt.el);
            var data = opt.data || {};

            this.el = el;
            this.data = data;

            this.bindText();
            this.bindModel();

            return this;
        };

        Shawn.prototype = {
            constructor: Hue,
            // **前端數據劫持**
            defineObj: function(obj, prop, value) {
                var _value = value || '', _this = this;

                try {
                    Object.defineProperty(obj, prop, {
                        get: function() {
                            return _value;
                        },
                        set: function(newVal) {
                            _value = newVal;
                            _this.bindText();
                        },
                        enumerable: true,
                        configurable: true
                    });
                } catch (error) {

                    // IE8+ 纔開始支持defineProperty,這也是Vue.js不支持IE8的原因
                    console.log("Browser must be IE8+ !");
                }
            },
            bindModel: function() {
                var modelDOMs = this.el.querySelectorAll('[shawn-model]'), lenModel = modelDOMs.length;

                var _this = this, i, propModel;

                for (i = 0; i < lenModel; i++) {
                    propModel = modelDOMs[i].getAttribute('shawn-model');

                    //init value
                    modelDOMs[i].value = this.data[propModel] || '';

                    // 前端數據劫持
                    this.defineObj(this.data, propModel);
                }

                addEvent(modelDOMs, 'keyup', function (e) {
                    _this.data[propModel] = e.target.value;
                })

            },
            bindText: function() {
                var textDOMs = this.el.querySelectorAll('[shawn-text]'),
                    lenText = textDOMs.length,
                    prppText,
                    j;
                for (j = 0; j < lenText; j++) {

                    propText = textDOMs[j].getAttribute('shawn-text');

                    textDOMs[j].innerHTML = this.data[propText] || '';
                }
            }
        };

        window.Hue = Hue;

    })(window);

    // test...
    new Shawn({
        el: '.app',
        data: {
            demo: 'Kenny',
            sha:123
        }
    });
</script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章