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 result;
}
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);
})

再次体现了封装的意义.

下面JavaScript高级框架设计(二) 将会开始介绍基本选择器的实现

JavaScript 框架设计的更多相关文章

  1. JavaScript框架设计(三) push兼容性和选择器上下文

    JavaScript框架设计(三) push兼容性和选择器上下文 博主很久没有更博了. 在上一篇 JavaScript框架设计(二) 中实现了最基本的选择器,getId,getTag和getClass ...

  2. JavaScript框架设计(四) 字符串选择器(选择器模块结束)

    JavaScript框架设计(四) 字符串选择器(选择器模块结束) 经过前面JavaScript框架设计(三) push兼容性和选择器上下文的铺垫,实现了在某一元素下寻找,现在终于进入了字符串选择器 ...

  3. 偶的《javascript框架设计》终于出版

    #cnblogs_post_body p{ text-indent:2em!important; } 历时两年多,我的书终于付梓出版了.应各方面的要求,写软文一篇,隆重介绍一下此书对各位程序员的钱途有 ...

  4. JS读书心得:《JavaScript框架设计》——第12章 异步处理

    一.何为异步   执行任务的过程可以被分为发起和执行两个部分. 同步执行模式:任务发起后必须等待直到任务执行完成并返回结果后,才会执行下一个任务. 异步执行模式:任务发起后不等待任务执行完成,而是马上 ...

  5. Javascript框架设计思路图

    这个系列的随笔都是关于Javascript框架设计一书的读书笔记(作者是司徒正美),不是本人原创!!! 一.简介: 1.市面上主流的JS框架,大多数是由一个个模块组合而成,模块化是大多数让软件所遵循的 ...

  6. JavaScript 框架设计(二)

    JavaScript 高级框架设计 (二) 上一篇,JavaScript高级框架设计(一)我们 实现了对tag标签的选择 下来我们实现对id的选择,即id选择器. 我们将上一篇的get命名为getTa ...

  7. 浅谈JavaScript框架设计

    在这个js框架随处乱跑的时代,你是否考虑过写一个自己的框架?下面的内容也许会有点帮助. 一个框架应该包含哪些内容? 1.语言扩展 大部分现有的框架都提供了这部分内容,语言扩展应当是以ECMAScrip ...

  8. javascript框架设计(读书笔记)

    我觉得多看几本进阶的书 与其十本书读一遍,不如一本书读十遍 读书的启示: 读好书(看推荐) 精读(重复看) 能读厚书(javascript权威指南) Object.keys Object.keys=O ...

  9. JavaScript框架设计 第14章 动画引擎

    easing-js <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...

随机推荐

  1. C#编写windows服务

    项目要求: 数据库用有一张表,存放待下载文件的地址,服务需要轮训表将未下载的文件下载下来. 表结构如下: 过程: VS--文件-->新建项目-->windows-->windows服 ...

  2. 可变字符串NSMutableString

    //可变字符串继承自字符串 //拼接 NSMutableString *string = [NSMutableString string]; [string appendString:@"今 ...

  3. 将Web应用发布到tomcat中的三种方法

    坑啊,为什么网易的博客不能搬过来!!!我一个一个复制过来容易嘛!!!!原文地址:http://buffalo-l.blog.163.com/blog/static/244954022201539111 ...

  4. mysql 表表连接的问题。

    select * from table a, table b where a.aid = b.bid and aid >100 这样连接,如果a有数据,b没有数据,  a.aid = b.bid ...

  5. C语言dll文件的说明以及生成、使用方法

    最近在搞一些小项目,由于要涉及到跟其它语言进行交互,动态链接库变成了不二的选择.为此也查阅了很多资料,将动态链接库的相关知识在此做一个整理. 一.动态链接库概述 动态链接库(Dynamic Link ...

  6. WPF整理-使用ResourceDictionary管理Logical Resources

    “Logical resources may be of various types, such as brushes, geometries, styles, and templates.Placi ...

  7. 各种android应用模仿源码

    V2EX的非官方Android客户端,极力遵循Material Design风格 下载 湘潭大学三翼校园"四季电台" Android客户端   下载   高仿煎蛋客户端    下载 ...

  8. UnderScore源代码阅读1

    读一下underscore源代码,用于自己学习,个人理解,如果有不对的地方希望指正,谢谢 我觉着阅读的顺序按照从整体到局部,从架构到细节较好. 1.整体架构 (function() {}.call(t ...

  9. Powershell 字符串处理案例

    有一张Excel表格收集了计算机名和IP地址,另外一张表有计算机名,需要找出这张表中计算机名对应的IP地址. #定义函数Get-LikeContentInfo function Get-LikeCon ...

  10. GDB十分钟教程

    原文链接: http://blog.csdn.net/liigo/archive/2006/01/17/582231.aspx 本文写给主要工作在Windows操作系统下而又需要开发一些跨平台软件的程 ...