支持IE6、IE7、IE8等低端浏览器的简化版vue

最近研究Vue的底层原理,写了一个简化版的Vue,可以在支持IE6、IE7、IE8等低端浏览器运行。由于低端浏览器不支持对象属性定义,所以设置属性不支持直接赋值,需要调用虚拟机实例的set方法。目前只实现了基础的方法,后续继续完善!

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 VMM(options){
    /**
     * 订阅器构造 用来接收属性值的相关数据的变化通知 从而更新视图
     *
     * @param {Object} vm 虚拟机对象
     * @param {HTMLElement} el Node节点
     * @param {String} attr 属性名称
     * @param {Object} val 属性值
     */
    function Watcher(vm, el, attr, val){
        this.vm = vm;
        this.el = el;
        this.attr = attr;
        this.val = val;
        /**
         * 将收到的新的数据更新在视图中
         */
        this.update = function() {
            if (this.vm.$data[this.val] === true) {
                this.el.style.display = ‘block‘;
            } else if (this.vm.$data[this.val] === false) {
                this.el.style.display = ‘none‘;
            } else {
                this.el[this.attr] = this.vm.$data[this.val];
            }
        }

        // 初始化订阅器时更新一下视图
        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));
            };
        // 迭代同级所有节点
        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) {
                this.compile(node); // 递归所有子节点
            }

             // 点击事件
            val=getAttr(node, ‘v-on: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);
}

原文地址:https://www.cnblogs.com/springwind2006/p/12441991.html

时间: 2024-08-02 10:51:00

支持IE6、IE7、IE8等低端浏览器的简化版vue的相关文章

让IE6/IE7/IE8浏览器支持CSS3属性

让IE6/IE7/IE8浏览器支持CSS3属性 一.下载 您可以狠狠地点击这里:ie-css3.htc,这个玩意儿是让IE浏览器支持CSS3表现的关键东东. 二.上面的是什么东西 首先说说.htc文件,.htc文件是个脚本文件,我个人以为与js文件属于同一货色,只是呢,貌似htc是Internet Explorer(IE)的私生子,只有IE才认它.htc文件可以用来描述web行为,web行为允许程序员把自定义的功能“连接”到现有的元素和控件,而不是必须让用户下载二进制文件(例如ActiveX 控

IE(IE6/IE7/IE8)支持HTML5标签--20150216

让IE(ie6/ie7/ie8)支持HTML5元素,我们需要在HTML头部添加以下JavaScript,这是一个简单的document.createElement声明,利用条件注释针对IE来调用这个js文件.Opera,FireFox等其他非IE浏览器就会忽视这段代码,也不会存在http请求. 方式一:引用google的html5.js文件,代码内容可以自己下载下来看. <!–[if lt IE9]> <script src="http://html5shiv.googleco

针对IE6,IE7,IE8,IE9,FF等不同浏览器的CSS写法

首先我们介绍一下HACK原理,就是不同浏览器对字符的识别不同 在 CSS中常用特殊字符识别表: (1)*: IE6+IE7都能识别*,而标准浏览器FF+IE8是不能识别*的; (2)!important: 除IE6不能识别 !important外, FF+IE8+IE7都能识别!important ; (3)_ : 除IE6支持_ 外, FF+IE8+IE7都不支持_; (4)\9:所有IE浏览器都识别(IE6.IE7.IE8.IE9) 示例: (1)区别FF(IE8)与IE6 IE7 back

让IE6/IE7/IE8支持HTML5标签的js代码方法

让IE(ie6/ie7/ie8)支持HTML5元素,我们需要在HTML头部添加以下JavaScript,这是一个简单的document.createElement声明,利用条件注释针对IE来调用这个js文件.Opera,FireFox等其他非IE浏览器就会忽视这段代码,也不会存在http请求. 方式一:引用google的html5.js文件,代码内容可以自己下载下来看. <!–[if lt IE9]> <script src="http://html5shiv.googleco

让IE6/IE7/IE8支持CSS3属性的8种方法介绍

我们都知道,IE浏览器暂不支持CSS3的一些属性.国外的工程师们,不安于此现状,他们总是尽量使用一些手段使IE浏览器也能支持CSS3属性,我觉得这些都是很有意义,很有价值的工作,可以推动整个技术领域的进步的.到目前为止,有不少可以让IE支持部分CSS3属性的工具.例如: 1. Dean Edwards的IE7.js (以及 IE8.js, IE9.js) 这个玩意估计是试图让IE支持CSS3属性的鼻祖,还算蛮强大,就是性能开销较大,要解析很多文件脚本,给DOM添加大量的元素以及ClassName

IE6 IE7 IE8 的函数声明和函数表达式的实现与其他浏览器有差异

标准参考 函数声明和函数表达式 定义一个函数有两种途径:函数声明和函数表达式. 函数声明: function Identifier ( FormalParameterList opt ) { FunctionBody } 函数表达式: function Identifier opt ( FormalParameterList opt ) { FunctionBody } ECMAScript 根据上下文来区分函数声明和函数表达式,假设 "function test(){}" 是一个表达

IE6 IE7 IE8(Q) 不支持 JSON 对象

标准参考 JSON 是一种数据交换格式,RFC 4627 对 JSON 进行了详细描述. 根据 ECMA-262(ECMAScript)第 5 版中描述,JSON 是一个包含了函数 parse 和 stringify 的简单对象. parse 函数用来解析一个 JSON 文本(一个 JSON 格式的字符串)到一个 ECMAScript 值(例如 JSON 对象被解析为 ECMAScript 对象, JSON 数组被解析为 ECMAScript 数组,其它类型以此类推):stringify 则相反

div+css 兼容ie6 ie7 ie8 ie9和FireFox Chrome等浏览器方法(非原创)

div+css 兼容ie6 ie7 ie8 ie9和FireFox Chrome等浏览器方法 1.DOCTYPE 影响 CSS 处理 2.FF: div 设置 margin-left, margin-right 为 auto 时已经居中, IE 不行 3.FF: body 设置 text-align 时, div 需要设置 margin: auto(主要是 margin-left,margin-right) 方可居中 4.FF: 设置 padding 后, div 会增加 height 和 wi

{转}div+css 兼容ie6 ie7 ie8 ie9和FireFox Chrome等浏览器方法

div+css 兼容ie6 ie7 ie8 ie9和FireFox Chrome等浏览器方法 1.DOCTYPE 影响 CSS 处理 2.FF: div 设置 margin-left, margin-right 为 auto 时已经居中, IE 不行 3.FF: body 设置 text-align 时, div 需要设置 margin: auto(主要是 margin-left,margin-right) 方可居中 4.FF: 设置 padding 后, div 会增加 height 和 wi