支持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);
}
支持IE6、IE7、IE8等低端浏览器的简化版vue的更多相关文章
- JS代码判断浏览器版本,支持IE6,IE7,IE8,IE9!三种方法!
web开发的时候有时候会用到JS检测IE的版本,下面是检测Microsoft Internet Explorer版本的三种代码! 方法一: <script type="text/jav ...
- JS代码判断IE6,IE7,IE8,IE9的函数代码
JS代码判断浏览器版本,支持IE6,IE7,IE8,IE9!做网页有时候会用到JS检测IE的版本,下面是检测Microsoft Internet Explorer版本的三种代码 做网页有时候会用到JS ...
- 让IE6/IE7/IE8浏览器支持CSS3属性
让IE6/IE7/IE8浏览器支持CSS3属性 一.下载 您可以狠狠地点击这里:ie-css3.htc,这个玩意儿是让IE浏览器支持CSS3表现的关键东东. 二.上面的是什么东西 首先说说.htc文件 ...
- 如何让低版本的IE浏览器(IE6/IE7/IE8)支持HTML5 header等新标签
html5提供的一些新标签(article,aside,dialog,footer,header,section,footer,nav,figure,menu)使用起来非常的方便,但是低版本的IE浏览 ...
- 解决IE6/IE7/IE8不支持before,after问题
对从事web开发的朋友来讲,低版本的IE永远是一个痛点,不支持最新技术(如css3,html5). 在现在web开发中使用图标字体已经很广泛,如Font Awesome,Bootstrap等,字体图片 ...
- IE6 IE7 IE8(Q) 不支持 JSON 对象
标准参考 JSON 是一种数据交换格式,RFC 4627 对 JSON 进行了详细描述. 根据 ECMA-262(ECMAScript)第 5 版中描述,JSON 是一个包含了函数 parse 和 s ...
- IE6 IE7 IE8 的函数声明和函数表达式的实现与其他浏览器有差异
标准参考 函数声明和函数表达式 定义一个函数有两种途径:函数声明和函数表达式. 函数声明: function Identifier ( FormalParameterList opt ) { Func ...
- 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法--(转)
如有雷同,不胜荣幸,若转载,请注明 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法 最近做一个Web网站,之前一直觉得bootstrap非常好,这次使用了boot ...
- 针对IE6,IE7,IE8,IE9,FF等不同浏览器的CSS写法
首先我们介绍一下HACK原理,就是不同浏览器对字符的识别不同 在 CSS中常用特殊字符识别表: (1)*: IE6+IE7都能识别*,而标准浏览器FF+IE8是不能识别*的; (2)!importan ...
随机推荐
- markdown 的一些字体
<font face='Comic Sans MS', size=5> 看看字体 1 one Hello 2 two Hello <font face='Kristen ITC', ...
- 1)public,provite和protect不能放在函数函数头
今天我才知道,原来这三个修饰的东西,只是用在类里面方法,怪不得一个叫方法,一个叫函数了,原来就是区分他们,哎, 今天遇到这么一个问题: <?php //header('Content-type: ...
- spring mvc 设置@Scope("prototype")
spring中bean的scope属性,有如下5种类型: singleton 表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例 prototype表示每次获得be ...
- 线程同步Lock锁
Lock接口历史 java1.5版本之前只有synchronized一种锁,lock是java1.5版本之后提供的接口.lock接口与synchronized接口功能相同,但是需要手动获取锁和释放锁. ...
- struts 2.1.8.1的sx:datetimepicker标签出现NaN错误的原因和解决办法
作者:Junsan.Jin 邮箱:junsanjin@gmail.com QQ:1305896503 本文原始地址:http://www.rsky.com.cn/Article/java/201 ...
- Java IO: 并发IO
原文链接 作者: Jakob Jenkov 译者: 李璟 有时候你可能需要并发地处理输入和输出.换句话说,你可能有超过一个线程处理输入和产生输出.比如,你有一个程序需要处理磁盘上的大量文件,这个任务可 ...
- 用数组实现栈(C++)
#include <iostream> //栈的数组实现 using namespace std; #define MAXSIZE 10; template<class T> ...
- 如何在linux中查找python安装包的路径
[root]# python -c "import fasttext;print(fasttext)"<module 'fasttext' from '/root/anaco ...
- SpringMVC之添加照片并修改照片名字
@RequestMapping(value="/addIdcardsSubmit",method={RequestMethod.POST,RequestMethod.GET}) p ...
- Python---5Python内置的有序集合-list和tuple
list Python内置的一种数据类型是列表:list,[ ].可以修改的集合. list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可以用一个list表示: ...