jQuery源码解读二

来源:互联网 发布:金进网络 编辑:程序博客网 时间:2024/06/06 16:40
$.callbacks----$.deferred --- $.data ---- $.queue

这几项彼此有依赖关系

六. jQuery.data

参考文章:
http://www.cnblogs.com/silin6/p/jQuery_data.html#data-2-x

6.1 引入背景

jQuery在1.2后引入jQuery.data(数据缓存系统),主要的作用是让一组自定义的数据可以DOM元素相关联——浅显的说:就是让一个对象和一组数据一对一的关联。

首先我们要搞清楚jQuery.data解决的需求,有一组和DOM相关/描述Element的数据,如何存放和挂载呢?可能有人是这样的:

  • 使用attributes
HTML:<div id="demo" userData="linkFly"></div>javascript:(function () {            var demo = document.getElementById('demo');            console.log(demo.getAttribute('userData'));})();
  • 使用HTML5的dataset
HTML:<div id="demo2" data-user="linkFly"></div>javascript:(function () {    var demo = document.getElementById('demo2');    console.log(demo.dataset.user);})();
  • 为DOM实例进行扩展
HTML:<div id="demo3"></div>javascript:(function () {    var demo = document.getElementById('demo3');    demo.userData = 'demo';    console.log(demo.userData);})();

虽然有解决方案,但都不是理想的解决方案,每个方案都有自己的局限性:
1、只能保存字符串(或转化为字符串类型)的数据,同时曝露了数据,并且在HTML上挂载了无谓的属性,浏览器仍然会尝试解析这些属性。
2、同上。
3、典型的污染,虽然可以保存更强大的数据(Object/Function),但是患有代码洁癖的骚年肯定是不能忍的,更主要,如果挂载的数据中引用着这个Element,则会循环引用
jQuery.data,则是为了解决这样的自定义数据挂载问题。

6.2 模型

jQuery.expando是当前页面中引用的jQuery对象的身份标志(id),每个页面引用的jQuery.expando都是不重复且唯一的,所以这就是钥匙的关键:jQuery.expando生成的值作为钥匙,挂载在Element上,也就是为Element创建一个属性:这个属性的名称,就是jQuery.expando的值,这就是钥匙的关键。 虽然仍然要在Element上挂载自己的数据,但是jQuery尽可能做到了最小化影响用户的东西。

当然这里需要注意:通过为Element添加钥匙的时候,使用的是jQuery.expando的值作为添加的属性名,页面每个使用过jQuery.data的Element上都有jQuery.expando的值扩展的属性名,也就是说,每个使用过jQuery.data的Element都有这个扩展的属性,通过检索这个属性值来找到仓库里的数据——钥匙是这个属性值,而不是这个jQuery.expando扩展的属性名。
这里写图片描述

6.3 $.extend.data 用法 以及 $.fn.extend.data(针对HTML5的dataset)用法

html:<!-- html5 dataset --><div id="testDataSetDiv" data-user="xyy" data-password="123"></div>js://$.data 用法//给普通对象赋值  取值var obj1 = {};$.data(obj1,{"name1":"tom","name2":"sam"});//赋值console.log(obj1);var getName1 = $.data(obj1,"name1");//读取值console.log(getName1);//tom//给DOM对象赋值 取值var jObj2 = $("#testDataSetDiv");$.data(jObj2,{"name1":"tom","name2":"sam"});var getName1 = $.data(jObj2,"name2");//读取值console.log(getName1);//sam//获取html5 data-开头属性var getNameVal = jObj2.data("password");//123console.log(getNameVal);jObj2.data("any","testset");//给元素挂载数据console.log(jObj2.data("any"));//testset

6.4 相关js知识

1.变量前 用 “+” 号
能将变量类型转换为number,即使变量值中不含数字

// Only convert to a number if it doesn't change the string//if条件表达式判断 data是否是数字字符串if ( data === +data + "" ) {        return +data;}

6.2 把横线形式连接的名称变为驼峰形式表示:

    // Matches dashed string for camelizing    rmsPrefix = /^-ms-/,    rdashAlpha = /-([a-z])/g,    // Used by jQuery.camelCase as callback to replace()    fcamelCase = function( all, letter ) {        return letter.toUpperCase();    };    // Convert dashed to camelCase; used by the css and data modules    // Support: IE <=9 - 11, Edge 12 - 13    // Microsoft forgot to hump their vendor prefix (#9572)    camelCase: function( string ) {        return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );    },

将驼峰形式表示转化为横线形式连接的名称:

var str = "smallCatBigTag";var rmultiDash = /[A-Z]/g;var str1 = str.replace( rmultiDash, "-$&" ).toLowerCase();console.log("str1: " + str1); //str1: small-cat-big-tag

关于正则表达式:
这里写图片描述

3 js == 与 === 的区别[转]
1、对于string,number等基础类型,==和===是有区别的
1)不同类型间比较,==之比较“转化成同一类型后的值”看“值”是否相等,===如果类型不同,其结果就是不等
2)同类型比较,直接进行“值”比较,两者结果一样
2、对于Array,Object等高级类型,==和===是没有区别的
进行“指针地址”比较
3、基础类型与高级类型,==和===是有区别的
1)对于==,将高级转化为基础类型,进行“值”比较
2)因为类型不同,===结果为false

4 JSON.parse 与 JSON.stringify
parse用于从一个字符串中解析出json对象,如

var str = '{"name":"huangxiaojian","age":"23"}'

结果:
JSON.parse(str)

Object1.  age: "23"2.  name: "huangxiaojian"3.  __proto__: Object

注意:单引号写在{}外,每个属性名都必须用双引号,否则会抛出异常。
stringify()用于从一个对象解析出字符串,如
var a = {a:1,b:2}
结果:
JSON.stringify(a)

"{"a":1,"b":2}"

七.jQuery.queue

参考文章:
http://www.tuicool.com/articles/MrYnA3R
http://www.cnblogs.com/rmbteam/archive/2011/07/25/2116357.html

jQuery中的queue和dequeue是一组很有用的方法,他们对于一系列需要按次序运行的函数特别有用。特别animate动画,ajax,以及timeout等需要一定时间的函数, animate方法其实就是一个入队和出队操作。

queue和dequeue的过程主要是:
1,用queue把函数加入队列(通常是函数数组)
2,用dequeue将函数数组中的第一个函数取出,并执行(用shift()方法取出并执行)

也就意味着当再次执行dequeue的时候,得到的是另一个函数了
同时也意味着,如果不执行dequeue,那么队列中的下一个函数永远不会执行

对于一个元素上执行animate方法加动画,jQuery内部也会将其加入名为 fx 的函数队列
而对于多个元素要依次执行动画,则必须我们手动设置队列进行了。

一个例子,要两个div依次向左移动

一般方法:

 $(“#block1″).animate({left:”+=100″},function() {  $(“#block2″).animate({left:”+=100″},function() {  $(“#block1″).animate({left:”+=100″},function() {  $(“#block2″).animate({left:”+=100″},function() {  $(“#block1″).animate({left:”+=100″},function(){  alert(“动画结束”);  });  });  }); }); });

用队列实现:

 var FUNC=[  function() {$("#block1").animate({left:"+=100"},aniCB);},  function() {$("#block2").animate({left:"+=100"},aniCB);},  function() {$("#block1").animate({left:"+=100"},aniCB);},  function() {$("#block2").animate({left:"+=100"},aniCB);},  function() {$("#block1").animate({left:"+=100"},aniCB);},  function(){alert("动画结束")}  ];  var aniCB=function() { $(document).dequeue(“myAnimation”); } $(document).queue(“myAnimation”,FUNC); aniCB();

1,首先建立了一个函数数组,里边是一些列需要依次执行的动画
2,然后定义了一个回调函数,用dequeue方法用来执行队列中的下一个函数
3,接着把这个函数数组放到document上的myAnimation的队列中(可以选择任何元素,只是为了方便而把这个队列放在document上)
4,最后开始执行队列中的第一个函数

这样做的好处在于函数数组是线性展开,增减起来非常方便。
而且,当不要要继续进行接下来动画的时候(比如用户点了某个按钮),只需要清空那个队列即可。而要增加更多则只需要加入队列即可

//清空队列$(document).queue(“myAnimation”,[]); //加一个新的函数放在最后 $(document).queue(“myAnimation”,function(){alert(“动画真的结束了!”)});
原创粉丝点击