JavaScript 高级框架设计
来源:互联网 发布:巨人网络2016财报 编辑:程序博客网 时间:2024/05/21 11:29
JavaScript 高级框架设计
在现在,jQuery等框架已经非常完美,以致于常常忽略了JavaScript原生开发,但是这是非常重要的.
所以,我打算写一个简单的框架,两个目的
熟练框架的思想
熟练DOM操作.
所以我打算,模仿jQuery,实现一个简单的类似jQuery的库 Hpawn.
关于JavaScript面向对象高级,会在以后介绍.
关于我所有的代码,都会托管到 github上,https://github.com/apawn
我的开发环境是VSCode.
在Hpawn中,我会分为六个模块.
- 选择器模块
- dom操作模块
- 事件模块(click,on) 比较简单
- 属性模块
- 样式模块
- 动画模块,使用缓动函数而不是css3.
- 面向对象封装
选择器模块
在这里,我们要实现一个类似于jQuery选择器的东西,但是要简单很多.
代码 01.html
<head> <meta charset="UTF-8"> <title>Document</title> <style> div{ width: 300px; height: 100px; border: 1px red solid; } </style></head><body> <div></div> <div></div> </body>
现在我们要给上面的div添加绿色背景,按照传统的办法,可能会这么写
01.js
onload = function(){ var divs = document.getElementsByTagName("div"); for(var i = 0,length = divs.length;i<length;i++){ divs[i].style.backgroundColor="green"; } }
但是,这样的DOM操作真的很麻烦.
代码冗余.丑,易错, 还会影响性能,为什么?
因为代码要压缩,因为document.getElementsByTagName()不会改变,但是如果改为get方法,只会存在一个g.
现在开始解决,首先解决代码冗余
02.js
先封装一个get方法
var get = function (tag) { return document.getElementsByTagName(tag);}
代码可能会变成现在这样,
var divs = get("div");for(var i = 0,length = divs.length;i<length; i++){ divs[i].style.background = "green"; }
但是,似乎还是很冗余,继续封装.
03.js
var get = function (tag) { return document.getElementsByTagName(tag);}var each = function (arr,style,value) { for(var i = 0,length = arr.length;i<length; i++){ arr[i].style[style] = value; }}var divs = get("div");each(divs,"backgroundColor","green") ;
代码变成了上面那样,有木有觉得好了很多呢.
可能并不觉得会简单,那是因为我只包含了两个元素.
但是,上面的代码只能做一件事情,就是设置样式,可是我还设置动作,设置属性.
好了,第一步优化完成,下面开始第二部.
04.js
var get = function (tag) { return document.getElementsByTagName(tag);}var each = function (arr,func) { for(var i = 0,length = arr.length;i<length; i++){ func(arr[i],i); }}var divs = get("div");each(divs,function (item,index) { item.style.background = "red"; });
我传递了一个函数进去,我将arr[i] 和i 传给函数,这是最关键的一步.
但是,一个问题出现了.
比如,我先查找数组 arr =[1,2,3,4] 中元素为3的索引,上面的代码可以吗?
我找到了,怎么跳出呢?
也许想到这样的代码
each(arr,function(v,i){ if(v===5){ breadk; }})
但是,break 可以写在函数中吗??
// 为了查看单独的js代码,我使用了node作为运行环境,所以代码库里有一些并没有对应的html文件.
还是需要再修改each 函数
05.js
var each = function (arr, func) { for (var i = 0, length = arr.length; i < length; i++) { if (func(arr[i], i) === false) { break; } }};var a = [1, 2, 3, 4];var index = -1;each(a, function (v, i) { if (v === 3) { index = i; return false; }});console.log(index); // 输出2
大功告成!
但是,我们每次调用函数的时候都要传一个v和i 才能使用,如果不小心忘了呢?
似乎有更好的办法
07.js,继续回到第一个例子
var get = function (tag) { return document.getElementsByTagName(tag);}var each = function (arr, func) { for (var i = 0, length = arr.length; i < length; i++) { if (func.call(arr[i],arr[i], i) === false) { break; } }};var divs = get("div");each(divs,function (item,index) { this.style.background = "red"; });
现在,我们看看jQuery的each是怎么实现的.
each: function( obj, callback, args ) { var value, i = 0, length = obj.length, isArray = isArraylike( obj ); else if ( isArray ) { for ( ; i < length; i++ ) { value = callback.call( obj[ i ], i, obj[ i ] ); if ( value === false ) { break; } } } else { for ( i in obj ) { value = callback.call( obj[ i ], i, obj[ i ] ); if ( value === false ) { break; } } } return obj; },
是不是差不多呢….
现在,继续优化get方法.
如果用get方法获得多个元素,就会获得多个数组,为了简化开发,可以考虑合并到一个数组中,调用多次get方法.
给get添加一个result参数
var get = function (tag, result) { result = result || []; result.push.apply(result, document.getElementsByTagName(tag)); return document.getElementsByTagName(tag);}var each = function (arr, func) { for (var i = 0, length = arr.length; i < length; i++) { if (func.call(arr[i], arr[i], i) === false) { break; } }};var divs = get("div");each(divs, function (item, index) { this.style.background = "red";});
但是,这里为什么要用apply呢?
因为document.getElementsByTagName() 返回一个伪数组,但是push方法只能接受真数组,在这里调用apply,因为apply接受的其他参数必须是一个数组,这里把document.getElementsByTagName() 的返回结果进行展开,然后一个一个push进去.
当然也可以这么写,但是性能肯定不及原生方法性能高.
each( document.getElementsByTagName(tag),function(){ result.push(this);})
再次体现了封装的意义.
下面将会开始进入get选择器.
- JavaScript 高级框架设计
- javascript高级程序设计---模式设计
- 浅谈JavaScript框架设计
- JavaScript框架设计
- 设计一个javascript框架
- JavaScript设计一个框架
- MVP项目框架搭建-高级设计
- MVP 项目框架搭建 — 高级设计
- Javascript框架的设计原则
- JavaScript 高级课程之缓冲/多个DIV运动框架
- Retrofit 框架设计+构建者+工厂模式高级应用
- Retrofit框架设计-构建者+工厂模式高级应用
- Retrofit框架设计-构建者+工厂模式高级应用
- Qt与Javascript交互框架设计
- Qt与Javascript交互框架设计 .
- javascript框架设计之种子模块
- javascript框架设计-种子模块一
- 《JavaScript高级语言设计》(第三版)学习笔记(1)
- java链表的数据结构和二叉树的实现
- (OK)(OK) Install Docker on Fedora 23
- 1.简介
- Java中的继承:父类和子类的关系
- Leetcode Unique Paths
- JavaScript 高级框架设计
- ROW_NUMBER()的用法
- SPAF
- java巩固再看回调函数
- ROW_NUMBER基本用法
- 【codeforces】HDD is Outdated Technology
- FZU-2140-Forever 0.5
- windows 进程通信之管道详解 :
- Fedora 24 安装配置 XX-Net