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 ); } });
  • 相关阅读:
    AngularJS Insert Update Delete Using PHP MySQL
    Simple task manager application using AngularJS PHP MySQL
    AngularJS MySQL and Bootstrap Shopping List Tutorial
    Starting out with Node.js and AngularJS
    AngularJS CRUD Example with PHP, MySQL and Material Design
    How to install KVM on Fedora 22
    Fake_AP模式下的Easy-Creds浅析
    河南公务员写古文辞职信
    AI
    政协委员:最大愿望是让小学生步行上学
  • 原文地址:https://www.cnblogs.com/hgonlywj/p/4868710.html
Copyright © 2011-2022 走看看