Support for IE6, IE7, IE8 and other low-end browsers simplified version of vue

Recent studies of the underlying principles of the Vue, wrote a simplified version of the Vue, you can run in support IE6, IE7, IE8 and other low-end browsers. Due to the low-end browser does not support the definition of object properties, so set the property does not support direct assignment, you need to call set methods virtual machine instance. Currently only implements a method based on follow-up continue to improve!

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>简化版Vue</title>
        <script>
            window.onerror=function(){
                return true;
            }
        </script>
    </head>
    <body>
        <hr />
        <div id="simpleVue">
            <button v-on:click="copy">戳我</button>
            <div>
                <textarea v-model="name"></textarea>
                <div v-text="name"></div>
            </div>
            <div>
                <select v-model="name">
                    <option value="name1" selected>name1</option>
                    <option value="name2">name2</option>
                    <option value="name3">name3</option>
                </select>
            </div>
            <hr>
            <button v-on:click="show">显示/隐藏</button>
            <div v-if="isShow">
                <input type="text" style="width: 300px" v-model="webSite">
                <div v-text="webSite"></div>
            </div>
        </div>
        <script src="vmm.js"></script>
        <script>
        var vm = new VMM({
            el: '#simpleVue',
            data: {
                name: '测试',
                webSite: 'https://github.com/steezer',
                isShow: true
            },
            methods: {
                copy: function(){
                    vm.set('name', this.name +'测试');
                },
                show: function(){
                    vm.set('isShow', !this.isShow);
                }
            }
        });
        </script>
    </body>

</html>

vmm.js

function the VMM (Options) {
     / * * 
     Change * subscriber related data attribute values configured to receive a notification to update the view 
     * 
     * @param {Object} VM virtual machine object 
     * @param {HTMLElement} el Node Node 
     * @param {String} attr attribute name 
     * @param {Object} val attribute value 
     * / 
    function Watcher (VM, EL, attr, Val) {
         the this .vm = VM;
         the this .el = EL;
         the this .attr = attr;
         the this .val = Val;
         / * * 
         * the new data received in the view update 
         * / 
        the this .Update = function () {
            IF ( the this .vm $ Data [. the this .val] === to true ) {
                 the this .el.style.display = 'Block' ; 
            } the else  IF ( the this .vm $ Data [. the this .val] === to false ) {
                 this .el.style.display = 'none' ; 
            } the else {
                 this .el [ this .attr] = this .vm $ Data [. this .val]; 
            } 
        } 
        
        // update the subscriber at the time of initialization view 
        this.update();
    }

    /**
     * 获取对象
     * 
     * @param {Object|String} id 
     * @returns Object
     */
    function getElem(id){
        if(typeof(id)=='object'){
            return id;
        }
        var target=id+'',
            prefix=target.substr(0,1),
            target=target.substr(1);
        if(prefix=='#'){
            return document.getElementById(target);
        }
        if(prefix=='.'){
            return document.getElementsByClassName(target);
        }
        return document.getElementsByTagName(target);
    }
    
    function getAttr(elem, name) {
        var node = elem.getAttributeNode(name);
        if (node && node.specified) {
            return node.nodeValue;
        } else {
            return undefined;
        }
    }
    
    function addEvent(node, type, handle){
        if(document.addEventListener){
            node.addEventListener(type, handle, false);
        }else{
            node.attachEvent('on'+type, function(){
                handle.call(node, arguments);
            });
        };
    }
    
    this.$el = getElem(options.el);
    this.$data = options.data;
    this.$methods = options.methods;
    this.oWatcherObj = {};
    
    // 获取属性
    this.get=function(key){
        return this.$data[key];
    }
    
    // 设置属性
    this.set=function(key, newVal){
        var value=this.$data[key];
        if (newVal !== value) {
            this.$data[key] = newVal;
            if(typeof(this.oWatcherObj[key])!="undefined"){
                var watchers=this.oWatcherObj[key];
                for(var i=0; i< watchers.length; i++){
                    watchers[i].update();
                }
            }
        }
    }
    
    /**
     * 节点DOM解析器
     */
    this.compile=function(el) {
        var nodes = el.children,
            $this=this,
            addWatcher=function(node, attr, val){
                if(typeof($this.oWatcherObj[val])=='undefined'){
                    $this.oWatcherObj[val]=[];
                }
                $this.oWatcherObj[val].push(new Watcher($this, node, attr, val));
            }; 
        // iteration all sibling nodes 
        var values = [];
         for ( var K in EL) { 
            values.push (K) 
        } 
        
        for ( var I = 0; I <nodes.length; I ++ ) {
             var Node = Nodes [I], Val;
             IF (node.children.length> 0 ) {
                 the this .compile (node); // recursive all child nodes 
            } 
            
             // click event 
            Val = getAttr (node, 'V-ON: the click' );
             IF (Val) {
                 IF(typeof($this.$methods[val])=="function"){
                    addEvent(node, 'click', (function(val){
                        return function(e){
                            $this.$methods[val].call($this.$data, e);
                        }
                    })(val));
                }
            }
            
            // IF指令
            val=getAttr(node, 'v-if');
            if (val) {
                addWatcher(node, "", val);
            }
            
            // Model
            val=getAttr(node, 'v-model');
            if (val) {
                var event=node.tagName.match(/select/i) ? 'change' : 
                        ('oninput' in node ? 'input' : 'propertychange');
                addWatcher(node, "value", val);
                addEvent(node, event, (function(i, val){
                    return function(e){
                        $this.set(val, nodes[i].value);
                    }
                })(i, val));
            }
            
            // Text
            val=getAttr(node, 'v-text');
            if (val) {
                addWatcher(node, "innerText", val);
            }
            
            // Html
            val=getAttr(node, 'v-html');
            if (val) {
                addWatcher(node, "innerHTML", val);
            }
        }
    }
    
    // 节点解析
    this.compile(this.$el);
}

 

Guess you like

Origin www.cnblogs.com/springwind2006/p/12441991.html