分析一个类似于jquery的小框架
在网上下了一个类似于jQuery的小框架,分析源码,看看怎么写框架。
选择器Select
- //用沙箱闭包其整个代码,只有itcast和I暴漏在全局作用域
- (function( window , undefined){
- //Itcast函数,参数:selector。返回值一个Itcast对象,功能:new Itcast。prototype。init()
- function Itcast(selector){
- return new Itcast.prototype.init();
- }
- // Itcast的原型属性用替换重新定义
- Itcast.prototype = {
- constructor: Itcast,
- type: "Itcast",
- length: 0,
- //constructor指向构造函数Itcast,type记录对象类型“Itcast”,length:变成伪数组
- // init函数 功能:Itcast对象的真正的构造函数,根据参数类型,进行不同的处理: 参数:selector。
- // 返回值:只要在适当的位置返回即可,构造函数不需要返回值,但是为了提醒这里是为了创建对象,所以写成return this
- //因为init是构造函数,this就是指创建出来的这个对象,现在要把获取到的dom对象全部追加到this中来,再通过Itcast返回
- // 。因为Itcast和init是用的同一个原型,所以认为此处创建出来的就是Itcast对象
- init:function(selector){
- var push = [].push;
- if( typeof selector == "string"){
- // 如果selector是html字符串,用parseHtml将其转成DOM伪数组,再转成this(Itcast伪数组)
- if( selector.charAt(0) == "<"){
- push.apply(this , parseHTML(selector));
- }else{
- // 如果selector是选择器。用Select函数,
- push.apply(this , Select(selector));
- }
- }
- // 如果是function ,近似于onload
- if( typeof selector == "function"){
- }
- // 如果是dom,追加到this(Itcast伪数组)中
- if( selector.nodeType ){
- }
- // 如果是Itcast对象,追加到新的Itcast对象中返回
- if( selector.type = "Itcast" ){
- }
- }
- }
- //让init的原型属性指向Itcast。prototype。即有init创建出来的对象也就是Itcast对象了
- Itcast.prototype.init.prototype = Itcast.fn = Itcast.prototype;
- //设定Itcast的扩展方式,Itcast。extend(静态成员扩展) 。 Itcast.prototype.extend(动态成员扩展)
- // .函数参数: 对象option。 返回值: 无, 功能:将option中的属性或方法依次添加给Itcast或Itcast.fn
- Itcast.fn.extend = Itcast.extend = function(option){
- for( var k in option){
- this[ k ] = option[ k ];
- }
- }
- //模块化,功能化。(构造函数的补充)
- //扩充静态成员
- //选择器Select(闭包,仅将Select暴漏在外面)参数:无,返回值Select函数。
- // 功能:再沙箱中将Select函数定义好,
- var Select = (function(){
- //数据初始化:
- //将某些浏览器是否支持a方法用对象support储存起来以免每一次动用函数的时候都要进行查找
- // 是否提供可以看函数体是否包含 [native code]即可;,正则表达式的变量以r开头
- var rnative = /\[native code\]/,
- push = [].push ,
- i,
- div = document.createElement("div");
- var support = {
- qsa: rnative.test(document.querySelectorAll),
- getByClass : rnative.test( document.getElementsByClassName),
- getByClass2: rnative.test(div.getElementsByClassName),
- trim: rnative.test(String.prototype.trim),
- indexOf: rnative.test(Array.prototype.indexOf),
- }
- // 要用的函数提前准备好
- // push,push没有兼容性问题但是push.apply再IE低版本,不能展开伪数组,会报错
- // ,因此用try{}catch的方法兼容
- try{
- push.apply([],document.getElementsByTagName("*"));
- }catch(e){
- //z自定义push.apply的函数,参数数组a,伪数组b, 返回值 数组a,
- // 功能:将b中的内容添加到 a当中;
- var push = {
- apply : function( a , b){
- for( var i =0 ; i< b.length ; i++ ){
- a[ a.length++ ] = b[ i ];
- }
- return a;
- }
- }
- }
- //trim 参数:字符串 ,返回值:首位去除空白的I字符串。功能:将字符串的两端的空白去出,并返回
- function trim( str ){
- if( support.trim ){
- return str.trim();
- }else{
- var rtrim = /^\s+|\s+$/;
- return str.replace( rtrim , "");
- }
- }
- // indexOf,参数数组arr,a要查找项,返回值:a的索引值,如果没有返回-1
- //indexOf 还需要一个参数, 就是 查找的开始位置
- function indexOf( arr , a,startIndex){
- startIndex = startIndex || 0;
- if(support.indexOf){
- return arr.indexOf(a , startIndex);
- }
- for(var i = startIndex; i< arr.length ;i++){
- if( arr[ i ] === a){
- return i;
- }
- }
- return -1;
- }
- //unique函数,参数:数组 ,返回值:去重之后的数组,功能: 将穿进来的数组中的重复项去除
- function unique( arr ){
- var array = [];
- for( var i=0 ; i< arr.length ;i++){
- if(indexOf( array ,arr[ i ]) == -1){
- array.push( arr[i]);
- }
- }
- return array;
- }
- //核心函数Select:参数:selector选择器, 要被添加元素的数组或伪数组results, 返回值results
- //功能: 将selector对应的DOM对象,追加到results中输出
- function Select(selector ,results){
- results = results || [];
- if( typeof selector !== "string"){
- return ;
- }
- //如果浏览器支持querySelectorAll就用,如果不支持,就自己定义一个select2
- if( support.qsa ){
- return document.querySelectorAll( selector );
- }else {
- return select2( selector);
- }
- }
- // select2,参数:selector选择器,返回值dom对象,
- function select2( selector ,results){
- // 功能:看选择器是不是并集选择器,将selector用trim函数去掉首尾的空白()
- results = results || [];
- // ,再用split函数切割成数组,
- var arr = selector.split(",");
- for( i = 0 ; i < arr.length ; i++){
- // 再用select3函数进行处理,将切割好的字符串用trim方法取出前后空白
- select3( trim(arr[ i ]) , results);
- }
- return unique(results);
- }
- function select3 ( selector , results){
- results = results || [];
- //select3函数:参数select ,返回值dom对象。功能:判断选择器是“*”还是id,还是类,还是标签
- var first = selector.charAt(0);
- //注意如果是类选择器,document.getElementsByClassName有浏览器兼容性问题。
- //区分好后,调用相应的函数进行处理
- //此处屏蔽掉后代选择器的影响,此时如果selector经过了首尾去空格后还有空格,说明是后代选择器
- if( selector.slice(" ").length == 1){
- if(selector == "*"){
- /*
- results = document.getElementsByTagName("*");
- return results;
- ,如果results原来就有内容,此处把results中的内容全部覆盖了所以不行,
- 要将选择器对应的dom元素挨个追加到results中
- */
- }else if( first == "#"){
- return id(selector.slice(1) , results);
- }else if( first == "."){
- //类
- return c(selector.slice(1),results);
- }else {
- //标签
- return t(selector , results)
- }
- }else{
- //如果是后代选择器,此处咱不处理,抛出一个bug,提示升级浏览器
- throw new Error("您的浏览器版本过低,请升级浏览器")
- }
- }
- //参数:选择器selector 被追加元素的数组。 返回值: results
- //功能: 将selector对应的元素挨个追加到results中并输出,
- function id( selector ,results ){
- results = results || [];
- push.apply(results , document.getElementById(selector));
- return results;
- }
- // 标签
- function t( selector , results){
- results = results || [];
- push.apply( results , document.getElementsByTagName( selector));
- return results;
- }
- //类,getElementsByClassName有浏览器兼容行问题,
- function c( selector , results ){
- results = results || [];
- push.apply( results , getByClass( selector , document));
- return results;
- }
- //兼容类选择器,参数:类名className ,查找返回node,返回值:返回查找到的dom元素数组
- //功能: 用className属性查找node中的符合条件的dom对象,并返回对象数组
- function getByClass(className , node){
- node = node || document;
- //如果浏览器支持
- if( node == document && support.getByClass || node.nodeType && support.getByClass2){
- return node.getElementsByClassName(className);
- }else{
- //如果浏览器不支持
- //获取所有的标签,遍历
- var list = node.getElementsByTagName("*"),
- arr = [],
- tempClassName;
- for( var i = 0 ; i< list.length ;i++){
- tempClassName = list[ i ];
- if( !tempClassName ){
- continue;
- } //再class属性存在的情况下
- //用slice(“ ”)分割
- //判断是否与className相同
- //如果相同追加到results中
- if(indexOf(tempClassName.slice(" "),className) !== -1){
- arr.push(tempClassName);
- }
- }
- return arr;
- }
- }
- return Select;
- })();
- // 解析html字符串parseHTML
- //在解析过程中,需要在内存中创建一个node,为了不暴漏在外面使用沙箱(自调自用的函数,返回该数组)
- //参数:selector,(html字符串),返回值存储dom的数组,功能: 将html字符串转化成dom对象储存在数组中
- Itcast.parseHTML =(function (){
- var node = document.createElement("div");
- var arr = [];
- function parseHTML(selector){
- node.innerHTML = selector;
- arr.push.apply(arr , node.childNodes);
- return arr;
- }
- return parseHTML;
- })();
- //扩充实例成员
- Itcast.fn.extend({
- appendTo: function ( parent , child ){
- parent.appendChild( child );
- }
- })
- //将Itcast挂在window上
- window.Itcast = window.I = Itcast;
- })(window);
分析一个类似于jquery的小框架的更多相关文章
- 分析一个类似于jquery的小框架 (2)
核心构造函数 (function ( window, undefined ) { // 定义Itcast构造函数 function Itcast ( selector ) { return new I ...
- 【JavaScript框架封装】实现一个类似于JQuery的基础框架、事件框架、CSS框架、属性框架、内容框架、动画框架整体架构的搭建
/* * @Author: 我爱科技论坛 * @Time: 20180715 * @Desc: 实现一个类似于JQuery功能的框架 * V 1.0: 实现了基础框架.事件框架.CSS框架.属性框架. ...
- 【JavaScript框架封装】实现一个类似于JQuery的DOM框架的封装
// DOM框架(选择器框架) (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 向现 ...
- 【JavaScript框架封装】实现一个类似于JQuery的缓存框架的封装
// 缓存框架 (function (xframe) { /** * 实现了缓存框架的临时存储功能(内存存储) * @type {{data: Array, get: (function(*): *) ...
- 【JavaScript框架封装】实现一个类似于JQuery的动画框架的封装
// 动画框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({}); // 不需要参与链式访问的 ...
- 【JavaScript框架封装】实现一个类似于JQuery的属性框架的封装
// 属性框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 获取/设置某一个元素 ...
- 【JavaScript框架封装】实现一个类似于JQuery的选择框架的封装
// 选择框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({}); // 不需要参与链式访问的 ...
- 【JavaScript框架封装】实现一个类似于JQuery的事件框架的封装
// 事件框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * 实现一个浏览器的基本 ...
- 【JavaScript框架封装】实现一个类似于JQuery的内容框架的封装
// 内容框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({ /** * .html()用为读 ...
随机推荐
- symfony2取得web目录绝对路径、相对路径、网址的函数是什么
对于你的需求,Symfony2通过DIC提供了kernel服务,以及request(请求)的封装. 在controller里(在其他地方你可以自行注入kernel,这个服务是HttpKernel库里的 ...
- putty远程连接ubuntu
步骤一.在ubuntu系统中安装ssh,可使用如下的命令进行安装: sudo apt-get install openssh-server步骤二.为了保险起见,安装完成后重启一下ssh服务,命令如 ...
- oracle中的日期:周月季年,首天未天。
SQL> SQL 前一小时数 FROM dual; 现在时间 当前小时数 前一小时数 ------------------- ---------- ---------- :: SQL> S ...
- Windows 查看端口占用和关闭进程
支持原创地址 :http://www.cnblogs.com/moodlxs/p/4145384.html 开始--运行--cmd 进入命令提示符 输入netstat -ano 即可看到所有连接的PI ...
- 将yyyyMMdd,dd/MM/yyyy 类型字符串转换为datetime 类型 yyyy-MM-dd C#
DateTime ConvertDate = DateTime.ParseExact(", "yyyyMMdd", null, System.Globalization. ...
- 无索引状态下比较DataTable的几种过滤方法效率
先构造一个DataTable: public DataTable GetDataTable() { DataTable dtTmp = new DataTable(); dtTmp.Columns.A ...
- ios启动载入启动图片
版本判断: 1.首先你要知道这个键值对的key:id key = (id)kCFBundleVersionKey; 2.同过本地的NSBundle取得当前的版本号. 3.在沙盒中取得对应的版本号. ...
- 重构MVC多条件+分页解决方案
为支持MVC的验证,无刷新查询,EF,以及让代码可读性更强一点,所以就重构了下原来的解决方案. 这里就简单讲下使用方法吧: Model: 继承PagerBase: 1 public class Sea ...
- MyEclipse中代码格式化后自动换行
MyEclipse的默认设置里面各种坑人,怎么不方便怎么设置,用户体验差到极点.今天又遇到个问题,按下Ctrl + Shift + F 后,自动格式化后的代码原来只有一行,结果变成了3行,看着都想吐. ...
- selenium 关于富文本的处理
http://www.cnblogs.com/xiaobaichuangtianxia/p/5889999.html