zoukankan      html  css  js  c++  java
  • jQuery 源码 : queue 主要针对animate这个操作

    
    queue	
    
    队列方法:执行顺序的管理。
    

    (1)jQuery用extend扩展,是有工具方法。
    
    jQuery.extend({
    	queue  			//	添加	类似数组的push
    	dequeue 		// 	删除	类似于 shift
    	_queueHooks		//	给传入的数据进行处理,加个 argu+queue。
    });
    
    
    注意:在	queue 和 dequeue	 中存入的必须是一个函数,其他格式不可以。
    
    例子:(1)
    
    工具方法使用。
    	function aaa() {
    		alert('aaa');
    	}
    
    	function bbb() {
    		alert('bbb');
    	}
    
    	$.queue(document, 'q1', aaa);		// 	这里创建了一个q1的队列。存入了一个值,是个函数aaa
    	$.queue(document, 'q1', bbb);		//    这里在去q1队列中加入了第二个值,是函数bbb
    
    	// $.queue(document, 'q1', [aaa, bbb]);		//也可以直接存入一个数组。
    	console.log( $.queue(document, 'q1') ); 	// FF 打印出	[aaa(), bbb()]。
    
    // 注意:queue 和 dequeue	 中存入的必须是一个函数。
    
    	$.dequeue(document, 'q1');			//  弹出 aaa函数 ,出队,只是把第一个函数取出来。并执行 aaa();
    	$.dequeue(document, 'q1');			//  弹出 bbb函数 ,出队,又把第一项给读取出来。并执行 bbb();
    //注意: dequeue,取出第一个变量,并执行它,其他的类型,无法执行。
    
    
    例子:(2)
    
    实例方法使用。
    
    	$(document).queue('p1', aaa);
    	$(document).queue('p1', bbb);
    	console.log( $.queue(document, 'p1') ); 		// FF 打印出	[aaa(), bbb()]。
    	$(document).dequeue('p1', bbb);			    // 打印 aaa函数。
    
    
    
    
    (2)jQuery.fn.extend 扩展的是实例方法。
    jQuery.fn.extend({
    	queue
    	dequeue	
    	delay		// 延迟队列
    	clearQueue
    	promise
    });
    
    
    	
    思考:队列的作用。
    	
    	$('#test').click(function () {
    		$(this).animate({ 400}, 2000);	      // (1)
    		$(this).animate({height: 400}, 2000);	      // (2)
    		$(this).animate({left: 200}, 2000);		 // (3)这里position要absolute
    
    		//  和上面一样。
    		//  $(this).animate({ 400}, 2000).animate({height: 400}, 2000).animate({left: 200}, 2000);
    	});
    
    //	这里的执行顺序是一次执行,不是并发执行。(1)-->(2)-->(3)
    //	用定时器开启,然后执行。但是定时器是异步操作。setInterval是异步操作。
    //	这个就是用队列实现的。
    
    当使用动作函数的时候,用 queue 依次将其中对函数压入队列fx。运行的时候,就 dequeue 操作。
    deferred 的是控制一个操作,queue 是控制一系列的操作。
    但是 deferred 针对异步操作,延迟对象更强大一些。主要针对的是一个异步操作的控制。
    queue是针对多个的。deferred很难完成多异步的操作。
    在 jQuery 中 queue 主要针对的是运动的操作,去解决连续运动的这个操作。
    
    
    例子
    
    A--------------------	使用规则
    	$(this).animate({ 400}, 2000).queue('fx', function () {
    		$(this).dequeue();		//	如果没有这个出队操作,后面的,就无法继续执行了。
    	}).animate({height: 400}, 2000).animate({left: 200}, 2000);
    	
    B---------------------	fx可以省略,并且如果调用函数,需要使用$(this).dequeue();
    //	这里的 fx 是可以省略的,默认就是。
    	$(this).animate({ 400}, 2000).queue(function () {
    		$(this).dequeue();		//	如果没有这个出队操作,后面的,就无法继续执行了。
    	}).animate({height: 400}, 2000).animate({left: 200}, 2000);
    
    
    C---------------------	传入的参数,等价于dequeue。
    
    	$(this).animate({ 400}, 2000).queue(function (next) {
    		$(this).css('left', 200);
    		next();
    	}).animate({height: 400}, 2000).animate({left: 200}, 2000);
    
    D-------------	利用回调函数的形式
    
    	$(this).animate({ 400}, 2000, function () {
    			$(this).css('left', 200);
    	}).animate({height: 400}, 2000).animate({left: 200}, 2000);
    
    E--------------------	可以通过控制queue,来控制,保证异步的顺序。
    	$(this).animate({ 400}, 2000).queue(function (next) {
    			
    		var _this = this;
    		var timer = setInterval(function () {
    			_this.style.height = ( _this.offsetHeight + 1 ) + "px";
    
    			if (_this.offsetHeight >= 400) {
    				next();		//	可以控制出队的时间,没有next的执行,就不会执行下一个动作。
    				clearInterval(timer);
    			}
    
    		}, 30);
    
    	}).animate({left: 200}, 2000);
    
    
    F--------------------	delay(2000) 延迟2秒钟
    
    $('#test').click(function () {
    
    	$(this).animate({ 400}, 2000).delay(2000).animate({left: 200}, 2000);
    
    });
    
    G---------------------	promise 所有运动执行完成以后,执行 promise 挂载的函数。
    $('#test').click(function () {
    
    	$(this).animate({ 400}, 2000).delay(2000).animate({left: 200}, 2000);
    
    	$(this).promise().done(function () {
    			alert('done');
    		});
    	});
    
    });



    源码: jQuery.extend({ queue: function( elem, type, data ) { var queue; // 当元素存在的时候 if ( elem ) { // 可以直接写一个type类型,不写默认就是fx type = ( type || "fx" ) + "queue"; queue = data_priv.get( elem, type ); // 如何往队列中存储,得到数组 // Speed up dequeue by getting out quickly if this is just a lookup // 如果存在第三个参数,就是传入的执行函数。 if ( data ) { // 判断 queue 是否存在,如果不存在,就执行,创建一个。 // 或者存入的 data 是数组,就重写,并覆盖以前的所有方法。搞一个新的 队列 queue 。 if ( !queue || jQuery.isArray( data ) ) { // 设定数据。 queue = data_priv.access( elem, type, jQuery.makeArray(data) ); } // 存在,就压入。 else { queue.push( data ); } } // 没有酒返回空数组,写2个参数,就返回集合。 return queue || []; } }, // 出队 dequeue: function( elem, type ) { // 不写就默认fx type = type || "fx"; // 先去得到 queue 的队列。 var queue = jQuery.queue( elem, type ), // queue 初始化。 startLength = queue.length, // 获取数组长度。 // 返回第一项。 fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), // 出队的操作 next(), 跟 dequeue 一回事。 next = function() { jQuery.dequeue( elem, type ); }; // If the fx queue is dequeued, always remove the progress sentinel // 当定时器结束的时候, 进行出队。 if ( fn === "inprogress" ) { fn = queue.shift(); startLength--; // 长度 - 1 } // 是否是函数。 if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued // 是默认情况下,就填入。 if ( type === "fx" ) { // inprogress 针对fx。添加 inprogress // 只有三处用了 inprogress。 // inprogress 的作用就是让队列,可以自动的进行出队的操作。 queue.unshift( "inprogress" ); // 只有第一次,添加 } // clear up the last queue stop function delete hooks.stop; // fn 是队列 刚退出来的函数, 传入参数, 进行call执行。 fn.call( elem, next, hooks ); } if ( !startLength && hooks ) { hooks.empty.fire(); } }, // not intended for public consumption - generates a queueHooks object, or returns the current one // 私有的函数,清理一下缓存。 // _queueHooks 的目的就是,将fx(默认),或者用户传入的的队列名,---->> 这些都是缓存到data中了, // 当全部结束的时候,将那些 fixqueue, 等,对咧名称,全部干掉。 _queueHooks: function( elem, type ) { var key = type + "queueHooks"; // data_priv.get( elem, key ) 取缓存,没有酒添加一个。 // return data_priv.get( elem, key ) || data_priv.access( elem, key, { empty: jQuery.Callbacks("once memory").add(function() { data_priv.remove( elem, [ type + "queue", key ] ); }) }); } }); 实例的源码 jQuery.fn.extend({ queue: function( type, data ) { var setter = 2; 判断是否是字符串。如果不是字符串,那么可能传入的是函数,或者数组。 if ( typeof type !== "string" ) { data = type; type = "fx"; setter--; } // 查看的状态 // 传入的参数小于2. if ( arguments.length < setter ) { return jQuery.queue( this[0], type ); // 返回一组元素的第一项。 } // 若果是空的话,就返回this对象,如果不是空,就要遍历了。 return data === undefined ? this : this.each(function() { var queue = jQuery.queue( this, type, data ); // ensure a hooks for this queue               //这里:_queueHooks了以后,看这个是不是空的,如果不是,就填入一个数据。 jQuery._queueHooks( this, type ); // 队列第0项,不是 inprogress 就出队,只是针对第一次出队操作,后续就不会了。 //    针对animate运动的。$(document).queue('p1', aaa).$(document).queue('p1', bbb); // 如果连续多个操作,第一个就直接执行了,然后第二个进入队列。
              // inprogress干的就是这个。保证执行第一个,后面的进行入队操作,等待前面的结束,激活后面的。 //    这里,$(document).queue('p1', aaa) 执行完,就要出队,然后再执行后面的动作。 // 这是一个入队方法,但是为什么调用出队呢? //    针对的就是这个 $(document).queue('p1', aaa) 第一个要直接运动起来。后面的压入队列,等待第一个执行结束,在进行后面的. // 逻辑比较简单
    if ( type === "fx" && queue[0] !== "inprogress" ) { // 出队 jQuery.dequeue( this, type ); //递归了。又重新调用。 } }); }, dequeue: function( type ) { return this.each(function() { jQuery.dequeue( this, type ); }); }, // Based off of the plugin by Clint Helfers, with permission. // // 延迟时间的。time == 600 delay: function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; return this.queue( type, function( next, hooks ) { // 这里搞了一个定时器,让你 time 时间以后,再进行出队操作。 var timeout = setTimeout( next, time ); hooks.stop = function() { clearTimeout( timeout ); }; }); }, // 清空 clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, // 这里和 Deferred 和 callbacks 里面的东西差不多。 // 就是等到运动结束了,执行个函数什么的, 让promise去执行就好了。 // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { var tmp, // 计数 count = 1, // Deferred 的对象 defer = jQuery.Deferred(), elements = this, i = this.length, // 累加多少,就减多少。 resolve = function() { // 直到 count == 0 的时候,才会执行这个 resolveWith--》》就是完成了---》》然后就是done。 // 这里就不存在fail了。 if ( !( --count ) ) { defer.resolveWith( elements, [ elements ] ); } }; if ( typeof type !== "string" ) { obj = type; type = undefined; } type = type || "fx"; while( i-- ) { tmp = data_priv.get( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { //这个队列存在的时候,就进行累加。 count++; tmp.empty.add( resolve ); // 添加事件 } } resolve(); // 内部函数调用, return defer.promise( obj ); } });
  • 相关阅读:
    《数据库原理》课程笔记 (Ch04-数据库管理系统)
    《数据库原理》课程笔记 (Ch03-数据库语言)
    《操作系统》课程笔记(Ch07-死锁)
    《数据库原理》课程笔记 (Ch02-数据模型)
    《数据库原理》课程笔记 (Ch01-引论)
    《计算机网络》课程笔记 (Ch02-应用层)
    《ES6标准入门》读书笔记 第5章
    《ES6标准入门》读书笔记 第4章
    《ES6标准入门》读书笔记 第3章
    《计算机网络》课程笔记 (Ch01-计算机网络和因特网)
  • 原文地址:https://www.cnblogs.com/hgonlywj/p/4868710.html
Copyright © 2011-2022 走看看