首页 > 编程语言 >深入学习jquery源码之queue()与dequeue()

深入学习jquery源码之queue()与dequeue()

时间:2023-02-23 22:04:41浏览次数:39  
标签:jquery jQuery cache elem queue 源码 div data


深入学习jquery源码之queue()与dequeue()

queue(element,[queueName])

概述

显示或操作在匹配元素上执行的函数队列

参数

element,[queueName] Element,String

element:检查附加列队的DOM元素

queueName:字符串值,包含序列的名称。默认是 fx, 标准的效果序列。

element,queueName,newQueue  Element,String,Array 

element:检查附加列队的DOM元素

queueName:字符串值,包含序列的名称。默认是 fx, 标准的效果序列。

newQueue:替换当前函数列队内容的数组

element,queueName,callback() Element,String

element:检查附加列队的DOM元素

queueName:字符串值,包含序列的名称。默认是 fx, 标准的效果序列。

callback():要添加进队列的函数

显示队列长度

<style>
div { margin:3px; width:40px; height:40px;
position:absolute; left:0px; top:30px;
background:green; display:none; }
div.newcolor { background:blue; }
span { color:red; }
</style>
<button id="show">Show Length of Queue</button>
<span></span>
<div></div>
$("#show").click(function () {
var n = $("div").queue("fx");
$("span").text("Queue length is: " + n.length);
});
function runIt() {
$("div").show("slow");
$("div").animate({left:'+=200'},2000);
$("div").slideToggle(1000);
$("div").slideToggle("fast");
$("div").animate({left:'-=200'},1500);
$("div").hide("slow");
$("div").show(1200);
$("div").slideUp("normal", runIt);
}
runIt();

通过设定队列数组来删除动画队列

<style>
div { margin:3px; width:40px; height:40px;
position:absolute; left:0px; top:30px;
background:green; display:none; }
div.newcolor { background:blue; }
</style>

<button id="start">Start</button>
<button id="stop">Stop</button>
<div></div>
$("#start").click(function () {
$("div").show("slow");
$("div").animate({left:'+=200'},5000);
$("div").queue(function () {
$(this).addClass("newcolor");
$(this).dequeue();
});
$("div").animate({left:'-=200'},1500);
$("div").queue(function () {
$(this).removeClass("newcolor");
$(this).dequeue();
});
$("div").slideUp();
});
$("#stop").click(function () {
$("div").queue("fx", []);
$("div").stop();
});

插入一个自定义函数 如果函数执行后要继续队列,则执行 jQuery(this).dequeue();

<style>
div { margin:3px; width:40px; height:40px;
position:absolute; left:0px; top:30px;
background:green; display:none; }
div.newcolor { background:blue; }
</style>
Click here...
<div></div>
$(document.body).click(function () {
$("div").show("slow");
$("div").animate({left:'+=200'},2000);
$("div").queue(function () {
$(this).addClass("newcolor");
$(this).dequeue();
});
$("div").animate({left:'-=200'},500);
$("div").queue(function () {
$(this).removeClass("newcolor");
$(this).dequeue();
});
$("div").slideUp();
});

 

dequeue([queueName])

概述

从队列最前端移除一个队列函数,并执行他。

参数

[queueName] String

队列名,默认为fx

使用 dequeue() 终止一个自定义的队列函数

$("div").queue(function () {
$(this).toggleClass("red");
$(this).dequeue();
});

用dequeue来结束自定义队列函数,并让队列继续进行下去。

<style>
div { margin:3px; width:50px; position:absolute;
height:50px; left:10px; top:30px;
background-color:yellow; }
div.red { background-color:red; }
</style>

<button>Start</button>
<div></div>
$("button").click(function () {
$("div").animate({left:'+=200px'}, 2000);
$("div").animate({top:'0px'}, 600);
$("div").queue(function () {
$(this).toggleClass("red");
$(this).dequeue();
});
$("div").animate({left:'10px', top:'30px'}, 700);
});

 

clearQueue([queueName])

概述

清空对象上尚未执行的所有队列

如果不带参数,则默认清空的是动画队列。这跟stop(true)类似,但stop()只能清空动画队列,而这个可以清空所有通过 .queue() 创建的队列。

参数

queueName Boolean

含有队列名的字符串。默认是"Fx",动画队列。

停止当前正在运行的动画:

$("#stop").click(function(){
$("#box").clearQueue();
});

 

jquery源码

jQuery.extend({
queue: function (elem, type, data) {
var queue;

if (elem) {
type = (type || "fx") + "queue";
queue = jQuery._data(elem, type);

// Speed up dequeue by getting out quickly if this is just a lookup
if (data) {
if (!queue || jQuery.isArray(data)) {
queue = jQuery._data(elem, type, jQuery.makeArray(data));
} else {
queue.push(data);
}
}
return queue || [];
}
},

dequeue: function (elem, type) {
type = type || "fx";

var queue = jQuery.queue(elem, type),
startLength = queue.length,
fn = queue.shift(),
hooks = jQuery._queueHooks(elem, type),
next = function () {
jQuery.dequeue(elem, type);
};

// If the fx queue is dequeued, always remove the progress sentinel
if (fn === "inprogress") {
fn = queue.shift();
startLength--;
}

if (fn) {

// Add a progress sentinel to prevent the fx queue from being
// automatically dequeued
if (type === "fx") {
queue.unshift("inprogress");
}

// clear up the last queue stop function
delete hooks.stop;
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: function (elem, type) {
var key = type + "queueHooks";
return jQuery._data(elem, key) || jQuery._data(elem, key, {
empty: jQuery.Callbacks("once memory").add(function () {
jQuery._removeData(elem, type + "queue");
jQuery._removeData(elem, key);
})
});
}
});

jQuery.fn.extend({
queue: function (type, data) {
var setter = 2;

if (typeof type !== "string") {
data = type;
type = "fx";
setter--;
}

if (arguments.length < setter) {
return jQuery.queue(this[0], type);
}

return data === undefined ?
this :
this.each(function () {
var queue = jQuery.queue(this, type, data);

// ensure a hooks for this queue
jQuery._queueHooks(this, type);

if (type === "fx" && queue[0] !== "inprogress") {
jQuery.dequeue(this, type);
}
});
},
dequeue: function (type) {
return this.each(function () {
jQuery.dequeue(this, type);
});
},
clearQueue: function (type) {
return this.queue(type || "fx", []);
}
});

/**
* Determines whether an object can have data
*/
jQuery.acceptData = function (elem) {
var noData = jQuery.noData[(elem.nodeName + " ").toLowerCase()],
nodeType = +elem.nodeType || 1;

// Do not set data on non-element DOM nodes because it will not be cleared (#8335).
return nodeType !== 1 && nodeType !== 9 ?
false :

// Nodes accept data unless otherwise specified; rejection can be conditional
!noData || noData !== true && elem.getAttribute("classid") === noData;
};


function internalData(elem, name, data, pvt /* Internal Use Only */) {
if (!jQuery.acceptData(elem)) {
return;
}

var ret, thisCache,
internalKey = jQuery.expando,

// We have to handle DOM nodes and JS objects differently because IE6-7
// can't GC object references properly across the DOM-JS boundary
isNode = elem.nodeType,

// Only DOM nodes need the global jQuery cache; JS object data is
// attached directly to the object so GC can occur automatically
cache = isNode ? jQuery.cache : elem,

// Only defining an ID for JS objects if its cache already exists allows
// the code to shortcut on the same path as a DOM node with no cache
id = isNode ? elem[internalKey] : elem[internalKey] && internalKey;

// Avoid doing any more work than we need to when trying to get data on an
// object that has no data at all
if ((!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string") {
return;
}

if (!id) {
// Only DOM nodes need a new unique ID for each element since their data
// ends up in the global cache
if (isNode) {
id = elem[internalKey] = deletedIds.pop() || jQuery.guid++;
} else {
id = internalKey;
}
}

if (!cache[id]) {
// Avoid exposing jQuery metadata on plain JS objects when the object
// is serialized using JSON.stringify
cache[id] = isNode ? {} : { toJSON: jQuery.noop };
}

// An object can be passed to jQuery.data instead of a key/value pair; this gets
// shallow copied over onto the existing cache
if (typeof name === "object" || typeof name === "function") {
if (pvt) {
cache[id] = jQuery.extend(cache[id], name);
} else {
cache[id].data = jQuery.extend(cache[id].data, name);
}
}

thisCache = cache[id];

// jQuery data() is stored in a separate object inside the object's internal data
// cache in order to avoid key collisions between internal data and user-defined
// data.
if (!pvt) {
if (!thisCache.data) {
thisCache.data = {};
}

thisCache = thisCache.data;
}

if (data !== undefined) {
thisCache[jQuery.camelCase(name)] = data;
}

// Check for both converted-to-camel and non-converted data property names
// If a data property was specified
if (typeof name === "string") {

// First Try to find as-is property data
ret = thisCache[name];

// Test for null|undefined property data
if (ret == null) {

// Try to find the camelCased property
ret = thisCache[jQuery.camelCase(name)];
}
} else {
ret = thisCache;
}

return ret;
}

function internalRemoveData(elem, name, pvt) {
if (!jQuery.acceptData(elem)) {
return;
}

var thisCache, i,
isNode = elem.nodeType,

// See jQuery.data for more information
cache = isNode ? jQuery.cache : elem,
id = isNode ? elem[jQuery.expando] : jQuery.expando;

// If there is already no cache entry for this object, there is no
// purpose in continuing
if (!cache[id]) {
return;
}

if (name) {

thisCache = pvt ? cache[id] : cache[id].data;

if (thisCache) {

// Support array or space separated string names for data keys
if (!jQuery.isArray(name)) {

// try the string as a key before any manipulation
if (name in thisCache) {
name = [name];
} else {

// split the camel cased version by spaces unless a key with the spaces exists
name = jQuery.camelCase(name);
if (name in thisCache) {
name = [name];
} else {
name = name.split(" ");
}
}
} else {
// If "name" is an array of keys...
// When data is initially created, via ("key", "val") signature,
// keys will be converted to camelCase.
// Since there is no way to tell _how_ a key was added, remove
// both plain key and camelCase key. #12786
// This will only penalize the array argument path.
name = name.concat(jQuery.map(name, jQuery.camelCase));
}

i = name.length;
while (i--) {
delete thisCache[name[i]];
}

// If there is no data left in the cache, we want to continue
// and let the cache object itself get destroyed
if (pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache)) {
return;
}
}
}

// See jQuery.data for more information
if (!pvt) {
delete cache[id].data;

// Don't destroy the parent cache unless the internal data object
// had been the only thing left in it
if (!isEmptyDataObject(cache[id])) {
return;
}
}

// Destroy the cache
if (isNode) {
jQuery.cleanData([elem], true);

// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
/* jshint eqeqeq: false */
} else if (support.deleteExpando || cache != cache.window) {
/* jshint eqeqeq: true */
delete cache[id];

// When all else fails, null
} else {
cache[id] = null;
}
}

jQuery.extend({
cache: {},

// The following elements (space-suffixed to avoid Object.prototype collisions)
// throw uncatchable exceptions if you attempt to set expando properties
noData: {
"applet ": true,
"embed ": true,
// ...but Flash objects (which have this classid) *can* handle expandos
"object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
},

// For internal use only.
_data: function (elem, name, data) {
return internalData(elem, name, data, true);
},

_removeData: function (elem, name) {
return internalRemoveData(elem, name, true);
}
});

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

标签:jquery,jQuery,cache,elem,queue,源码,div,data
From: https://blog.51cto.com/u_11837698/6081935

相关文章

  • 深入学习jquery源码之序列化表单
    深入学习jquery源码之序列化表单serialize()概述序列表表格内容为字符串。序列表表格内容为字符串,用于Ajax请求。<pid="results"><b>Results:</b></p><form><select......
  • 深入学习jquery源码之jQuery的核心参数
    深入学习jquery源码之jQuery的核心参数jQuery([selector,[context]])概述这个函数接收一个包含CSS选择器的字符串,然后用这个字符串去匹配一组元素。jQuery的核心功能都是......
  • 深入学习jquery源码之is()与not()
    深入学习jquery源码之is()与not()is(expr|obj|ele|fn)概述根据选择器、DOM元素或jQuery对象来检测匹配元素集合,如果其中至少有一个元素符合这个给定的表达式就返回true。......
  • 深入学习jquery源码之arguments和callee
    深入学习jquery源码之argumentsjs中的函数其实是对象,函数名是对Function对象的引用,arguments这个对象不能显式创建,arguments对象只有函数开始时才可用。每创建一个函数,该......
  • 深入学习jquery源码之filter()与find()
    深入学习jquery源码之filter()与find()filter(expr|obj|ele|fn)概述筛选出与指定表达式匹配的元素集合。这个方法用于缩小匹配的范围。用逗号分隔多个表达式参数expr Strin......
  • 深入学习jquery源码之prop()与removeProp()
    深入学习jquery源码之prop()与removeProp()prop(name|properties|key,value|fn)概述获取在匹配的元素集中的第一个元素的属性值。随着一些内置属性的DOM元素或window对象,如......
  • 深入学习jquery源码之addClass()和toggleClass()与hasClass()
    深入学习jquery源码之addClass()和toggleClass()与hasClass()addClass(class|fn)概述为每个匹配的元素添加指定的类名。参数class String一个或多个要添加到元素中的CSS类......
  • 深入学习jquery源码之siblings()和children()与contents()
    深入学习jquery源码之siblings()和children()与contents()siblings([expr])概述取得一个包含匹配的元素集合中每一个元素的所有唯一同辈元素的元素集合。可以用可选的表达式......
  • 深入学习jquery源码之jQuery中高质量的代码
    深入学习jquery源码之jQuery中高质量的代码1、this指向的问题 functionStudent(name,age,grade,school){Person.apply(this,arguments);}他就具备了Pe......
  • 深入学习jquery源码之next()和nextAll()与nextUntil()
    深入学习jquery源码之next()和nextAll()与nextUntil()next([expr])概述取得一个包含匹配的元素集合中每一个元素紧邻的后面同辈元素的元素集合。这个函数只返回后面那个紧邻......