jQuery源码解读二

$.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");//123
console.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)

Object
1.  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(“动画真的结束了!”)});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值