闭包结构

为了防止和别的库的冲突,用闭包把整个框架安全地保护好。

我们待会的代码都写在里面。这里创建一个全局变量"window.O",就是在window对象里加个O,它等价于 "Oct",相当于jquery、Jquery这样的别称,意味着以后用Oct()或O()来进行操作。把window.O写成window.$,那就和JQ的$调用用法一样。window.O返回一个Octobj对象,这很重要。

(function() {
// 创建一个全局变量"window.O"
window.O = Oct = function(selector, root_id, tag) {
return new Octobj(selector, root_id, tag);
}; // 帅气地定义一个版本
Oct.version = "1.0"; })();

链式结构原理

JQ的流行,我想是因为它很方便吧,一个选择器就可以接着写一连串的方法。链式结构就是在每个方法结束时返回一个对象进行下一个方法的操作。后面会通过代码说明

选择器

选择器非常重要。JQ特别把选择器部分剥离出一个库sizzle.js。现在的JQ内部也是调用JQ里面的sizzle。“选择器”三个字写得简单,代码写起来就很有学问,sizzle.js这种高大上的我就不说了。我这里简单实现一些功能:选择class/id/标签。

首先,把上面的Octobj对象骨架搭建起来。包含selector, root_id, tag三个参数。selector就是你想要找的东西,root_id是你想要找的东西的上级的id,tag是你要指定返回某种标签。

var Octobj = function(selector, root_id, tag) {

};

定义一些参数

// args: 存储root_id的子标签
// type: 类型标记,id("#"), class(".") 或者 tag("&。 tag也加标记是为了代码方便
// eles: 临时的,存储`selector`变量里"# . &"标记后面的字符串
// selector_exp: 用来匹配标签的正则规则
var agrs, type, eles;
var selector_exp = /^(?:#(\w-_)+|\.(\w-_)+|(\w)+)$/; // this.elements: 存储函数结束后返回对象
this.elements = []; // 防止以下情况: $(""), $(null), $(undefined), $(false)
if (!selector) {
return this;
}

接下来处理有没有指定root_id、tag的情况,

if (root_id) {
root_id = typeof root_id == "string" ? document.getElementById(root_id) : root_id;
} else {
root_id = document.body;
}
tag = tag || "*";
if (tag !== "*") {
tag = tag.slice(1);
}

进入核心部分。分两种情况,能支持querySelector()方法的“高级”浏览器和不能支持的“低端”浏览器。先是能支持querySelector的,就很简单了:

if (document.querySelectorAll) {
// 因为我用'&'符号来标记标签 ,所以要用"replace()"去掉'&'
var node_list = document.querySelectorAll(selector.replace("&", ""))
for (var i in node_list) {
if (node_list[i].tagName !== undefined) {
// 把符合要求的元素存入`this.elements`
this.elements.push(node_list[i]);
}
}
}

不能支持querySelector的,先来设置一些参数:

// 处理类似JQ $('.a .b')的情况
selector = selector.replace(/^\s+/, "").split(/\s+/); // 如果不指明 "root_id" 和 "tag", "args" 就存储所有的标签
args = root_id.getElementsByTagName(tag); // 通过符号标记判断是class/id/tag
type = selector[0].charAt(0); // 所要选取的目标的字符串
eles = selector[0].slice(1);

处理选择class的情况。有文章指出for in的效率不高,我本来是用for处理的,但是出现问题,因为会把方法一起选进来。JQ用了for in,感觉有了标杆,我就全部改用for in了。

if (type === ".") {
// 查找每个标签中有className,提取处理进行匹配
for (var i in args) {
if(args[i].className) { // className 可能不止一个, 通过空格进行分割
var r = args[i].className.split(/\s+/);
for (var j in r) {
if (r[j] === eles) {
this.elements.push(args[i]);
}
}
}
}
}

处理选择id的情况:

else if (type === "#") {
for (var i in args) {
if(args[i].id) {
var r = args[i].id.split(/\s+/);
for (var j in r) {
if (r[j] === eles) {
this.elements.push(args[i]);
}
}
}
}
}

处理选择标签的情况:

else if (type === "&") {
for (var i in args) {
// 你可以"console.log(args[i]);" 可以看到最后一个是"length" ,没有"tagName",所以要排除这个情况,否则会报错
if (i !== "length" && typeof args[i] !== "function") { // "args[i].tagName" 在浏览器的属性里是用大写的,为了符合我的习惯,改用小写进行判断
if (args[i].tagName.toLowerCase() === eles.toLowerCase()) {
this.elements.push(args[i]);
}
}
}
}

基础选择器部分完成了,别忘了最后一句,返回找到的元素,给下一个方法进行操作:

return this;

用法举例

1.通过 id 选择.

O("#buddy")

2.通过 class 选择.

Oct(".buddy")

3.选择所有 div.

O("&div") // also O("&Div"), O("&DIV")

4.选择 .buddy 里的 <p>.

O(".buddy", null, "&p")

5.选择#dad下的.buddy

O(".buddy", "#dad")   

摘自:https://segmentfault.com/a/1190000002465399

JS框架的一些小总结的更多相关文章

  1. 微信js框架第二篇(创建完整界面布局)

    接着昨天的继续谈关于微信新出的这个js框架,今天主要谈一个页面的创建到布局的详细步骤. 一.创建一个完整页面       页面你可以创建在项目的任何节点,只要你在入口文件正确引入创建该页面的路径就可使 ...

  2. js框架简明

    jquery 主要战场还是在dom这块.其它经典怀旧的2个需要了解一下,mootools, prototype.是他们启发了js向工程化,团队化,协作化发展的转变,yui虽然听说停止开发了,但他的代码 ...

  3. JS框架整理

    1. Dojo (演示地址) Dojo是一个强大的面向对象JavaScript框架.主要由三大模块组成:Core.Dijit.DojoX.Core提供ajax,events,packaging,CSS ...

  4. 8款JS框架比较

    Dojo     Dojo 是目前最为强大的JS框架,它在自己的 Wiki 上给自己下了一个定义,Dojo 是一个用 JavaScript 编写的开源的DHTML工具箱.Dojo 很想做一个“大一统” ...

  5. js 框架都有哪几种(转载)

    目前来看,js框架以及一些开发包和库类有如下几个,Dojo .Scriptaculous .Prototype .yui-ext .Jquery .Mochikit.mootools .moo.fxD ...

  6. 你需要了解的JS框架

    excanvas.js/Chart.js/cubism.js/d3.js/dc.js/dx.chartjs.js/echarts.js/flot.js       用途:构建数据统计图表,兼容多浏览器 ...

  7. 媲美jQuery的JS框架——AngularJS(一)

    前言 相信原生JS大家都不陌生,至于为什么说原生,是因为在JS的基础上衍生出了很多的框架.有些框架的使用非常广泛,甚至已经达到了媲美原生的地步.在之前的文章中给大家介绍了jQuery这一介绍框架.今天 ...

  8. Vue 浅谈前端js框架vue

    Vue Vue近几年来特别的受关注,三年前的时候angularJS霸占前端JS框架市场很长时间,接着react框架横空出世,因为它有一个特性是虚拟DOM,从性能上碾轧angularJS,这个时候,vu ...

  9. vue_简介_渐进式 js 框架_内置指令_自定义指令_自定义插件

    vue 尤雨溪 华裔 Google 工程师 遵循 MVVM 模式 编码简洁,体积小,运行效率高,适合 移动 / PC 端 开发 动态构建用户界面: 异步获取后台数据,展现到页面 渐进式 js 框架 渐 ...

随机推荐

  1. ios 数组排序

    第一种:利用数组的sortedArrayUsingComparator调用 NSComparator  示例: obj1和obj2指的是数组中的对象 //1.数组中存放的是字符 NSComparato ...

  2. Android Material Design控件学习(一)——TabLayout的用法

    前言 Google官方在14年Google I/O上推出了全新的设计语言--Material Design.一并推出了一系列实现Material Design效果的控件库--Android Desig ...

  3. Win7上Git安装及配置过程

    Win7上Git安装及配置过程 文档名称 Win7上Git安装及配置过程 创建时间 2012/8/20 修改时间 2012/8/20 创建人 Baifx 简介(收获) 1.在win7上安装msysgi ...

  4. 【cs229-Lecture17】离散与维数灾难

    主要内容: 解决MDP问题的算法: 离散化: 模型MDP的同化型: (model/similator) 拟合值迭代算法: Q函数: 近似政策迭代: 笔记转自:http://blog.csdn.net/ ...

  5. `cocos2dx非完整` 开始自己的FW模块

    上一篇的文章中说到了一些个人习惯的东西以及一些简单的项目配置,这一篇文章我们来进一步完善一些东西.首先,打开编译以后的客户端执行,会看到一大堆的fileutils加载luac文件的提示,在终端显示一大 ...

  6. excel导入记录

    use DangJianSELECT vale1, value2 into Table2 from Table1 select COUNT(*) from tmpdangyuan where 手机号 ...

  7. Reinforcement Learning

    Q-learning 高潮博文 http://mnemstudio.org/path-finding-q-learning-tutorial.htm 模式识别与机器学习的区别. http://www. ...

  8. html5 audio/video 的那些坑

    当我最近项目用到audio的时候,我们用到了jPlayer作为三方库. 功能实现了,暂停播放,进度条什么的,都很顺利的搞定了.后来考虑到当网速过慢时需要给播放按钮一个载入动画,然后就一发不可收拾了. ...

  9. python第三方模块精选

    python不但有着强大丰富的“内置电池”,同样的,第三方模块也是非常的多.目前收集了requests.paramiko.pymsql,以后会陆续添加: 一.requests Python标准库中提供 ...

  10. C语言中的经典例题用javascript怎么解?(一)

    C语言中的经典例题用javascript怎么解?(一) 一.1+2+3+……+100=?        <script type="text/javascript">  ...