jQuery中的queue和dequeue是一组很有用的方法,他们对于一系列需要按次序运行的函数特别有用。特别animate动画,ajax,以及timeout等需要一定时间的函数
queue和dequeue的过程主要是:
1,用queue把函数加入队列(通常是函数数组)
2,用dequeue将函数数组中的第一个函数取出,并执行(用shift()方法取出并执行)
也就意味着当再次执行dequeue的时候,得到的是另一个函数了
同时也意味着,如果不执行dequeue,那么队列中的下一个函数永远不会执行
对于一个元素上执行animate方法加动画,jQuery内部也会将其加入名为 fx 的函数队列
而对于多个元素要依次执行动画,则必须我们手动设置队列进行了。
一个例子,要两个div依次向左移动,点击这里查看
div {
background:#aaa;
width:18px;
height:18px;
position:absolute;
top:10px;
}
如果只是轮流移动次数较少,可以使用animate的回调函数来做,一个动画放在另一个动画的回调里边
比如
$(“#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(“动画结束”);
});
});
});
});
});
但这种方法当动画较多的时候简直是残忍。
此时利用queue和dequeue则显得简单很多:
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(“动画真的结束了!”)});
以前发过一个wait插件,用于让动画之间可以暂停一段时间
http://shawphy.com/2008/07/enabling-settimout-within-chained-functions-in-jquery.html
可以看一下,他也就是利用了这个原理,默认在fx中插入一个timeout,放到队列中,直到timeout结束后才执行dequeue继续执行队列中的下一个函数。
这当然也可以用于ajax之类的方法,如果需要一系列ajax交互,每个ajax都希望在前一个结束之后开始,之前最原始的方法就是用回调函数,但这样太麻烦了。同样利用queue添加队列,每次ajax之后的回调中执行一次dequeue即可。
如果没有使用jQuey库,也可以自己写段简易代码来解决这个问题。
来自:http://shawphy.com/2009/04/how-to-use-queue-and-dequeue.html
在用jQuery做类似多级联动效果时遇到的问题,具体流程为:

标题有些拗口,看不懂标题的看下文,看不懂下文的call me~
今天在做追信API2.0处理分页时用到了正则替换,直接贴代码:
}
这个是之前优化追信客户端时写的代码,今天提取出来又补充了点东西(由于之前客户端没有涉及到下拉菜单(select),所以没有针对它做适配,现已加上).
当时的需求是这样的:根据接口返回的信息生成表单,所以不能预先知道表单的名(name)和值(value)。不同的栏目生成不同的表单,同一个函数处理这些生成的表单,最重要的一点是:当在不能用jQuery的环境中(nokia widget).
HTML代码:
<form id=”testForm”>
<label>姓名:</label><input type=”text” name=”user”/><br/>
<label>密码:</label><input type=”password” name=”pass”/><br/>
<label>性别:</label><input type=”radio” name=”sex” value=”1″/>男<input type=”radio” name=”sex” value=”0″/>女<br/>
<label>出生年份:</label><select name=”year”><option value=”1980″>1980</option><option value=”1981″>1981</option><option value=”1982″>1982</option></select>(option务必加value属性)<br/>
<label>喜好:</label><input type=”checkbox” name=”fav” value=”0″/>读书<input type=”checkbox” name=”fav” value=”1″/>上网<input type=”checkbox” name=”fav” value=”2″/>旅游<br/>
<button name=”more”>test</button><br/>
<input type=”submit” name=”sub” id=”formSub” value=”提交”/>
</form>
JS代码:
<script type=”text/javascript”>
function $(ele){
if (typeof ele == “object”) {
return ele;
}
else
if (typeof ele == “string” || typeof ele == “number”) {
return document.getElementById(ele.toString());
}
else {
return false;
}
}
function serialize(formID){
var form;
if (typeof formID == “object”) {
form = formID;
}
else {
form = $(formID);
}
var param = “”;
for (var i = 0; i < form.length; i++) {
if (form[i].type == “radio” || form[i].type == “checkbox”) {
if (!form[i].checked) {
continue;
}
}
if (form[i].type == “submit”) {
continue;
}
var name = form[i].name;
var val = form[i].value;
param += name + “=” + val + “&”;
}
return param.substr(0, param.length – 1);
}
$(“formSub”).onclick = function(){
$(“result”).innerHTML = serialize(“testForm”);
return false;
}
</script>
最近在用jquery的ajax方法传递接收json数据时发现一个问题,那就是返回的data数据,有时候可以直接作为json数据使用,可有时候又不行。
经过网友指出,这个问题已经有了比较明确的结论,那就是jquery ajax方法的complete方法是不会处理dataType的,所以如果你是在complete里面试图直接用json数据是不可行的,必须先通过eval。
以下是我原来的文章,大家仅作个参考,已经没有太大价值了。
$.ajax方法如下:
Java代码
$.ajax({
type: “POST”,
url: ctxRoot+’FolderAction!saveInformSetting.action’,
data: ‘jsonStr=’ + inform_settingListStr,
dataType: “json”,
complete: function(data){
//在这里做些事情,假设返回的json数据里有name这个属性
//有时候可以直接data.name或者data['name']去访问
//但有时候,却要通过var jsonData = eval(“(“+data.responseText+”)”);才可以通过jsonData.name访问,而且这种情况下,需要是complete而不是success
}
});
ok, 问题已经在代码的注释里面说明了,下面说下造成这两种不同的原因。
先说明第一种情况:
我发现能够直接 data.属性名访问的情况,服务器端代码一定是直接renturn的一个常量字符串。
什么是常量字符串呢,有些人可能不太清楚,常量字符串就是指直接用“”组成的字符串,没有定义String 变量直接把一串“”print到前台的情况,就可以直接data.属性名访问,而且jquery端只要写success就可以拿到。
下面是造成要eval并且不能进入success的原因:
这种情况是因为服务器端向外print的时候是一个String对象,通常此类问题在我的代码里是因为后台json比较复杂,在组织的时候我用到了StringBuffer,然后最后print的时候print的是StringBuffer对象的toString,所以就相当于print了一个String对象
这种情况下jquery的ajax方法就不会进入success方法,只能用complete接收,并且想要解析data里的json数据的话,必须对data.responseText进行eval
除此两点,还有需要注意的是,如果你使用的是jq1.4,那么他对json的格式有着更严格的要求,所有的key和属性都要用双引号标注起来,虽然key不用双引号原生的js是允许的,但是jq1.4似乎有这个要求。
以上就是我个人对于这一问题的一些想法和体会,如果有片面或者不正确的地方,欢迎大家评论指正,谢谢。
From:http://www.javaeye.com/topic/722028
这次是我第四次参加《web标准交流会》,因为最近工作挺忙,所以没能及时关注WEB标准交流会网站,当我看到本期话题《前端工程师应该如何学习javascript》时,眼前一亮。由于前几次话题大多是分享工作中部门之间配合,而很少有这种纯技术的话题(也可能是我参加的次数不多,错过了以前的技术讨论).
这次交流会解决了我最近工作中遇到的一个JavaScript跨域调用数据的问题。就我个人来说,平时工作中使用Ajax无非以下几种:
1.基本调用(代码片段):
var request=new XMLHttpRequest(); //仅作参考
request.open(“GET”,url,true);
request.onreadystatechange=function(){…};
request.send(”);
2.使用jQuery框架(代码片段):
$.ajax({
type:”GET”,
url:”",
data:{},
beforeSend:function(){…},
success:function(){….},
error:function(){…}
})
3.jQuery的$.getJSON(url,data,callback),即JSONP技术;
和上面2相比差异如下:
优点 :跨域;
缺点:不提供错误处理,如果动态插入的代码正常运行,你可以得到返回,但是如果失败了,那么什么都不会发生。你无法获得一个404的错误,也不能取消这个请求。我处理的方式可见$.getJSON的错误处理(原创)
重点来了:
虽然上面这些方法在处理常规的交互已经足够了,不过我有个需求:不使用jQuery框架实现JSONP功能。其实这个从原理上来讲写起来并不难,
下面是我的最初版:
定义函数:
function getJSON ( url , func ){
}
回调函数:
}
页面调用:
}
虽然可以实现效果,但是代码凌乱,不便重用。
今天在会上请教JavaScript大牛后代码如下:
定义函数:
function getJSON(url, func){
if (!document.getElementById) {
return false;
}
if (document.getElementById(“jsonscript”)) {
var oldscript = document.getElementsByTagName(“script”);
for (var i = 0; i < oldscript.length; i++) {
if (oldscript[i].getAttribute(“src”) == url) {
oldscript.parentNode.removeChild(oldscript);
}
}
}
var script = document.createElement(“script”);
var rnd=parseInt(Math.random()*1e8);
url+=”?jsoncallback=callback”+rnd;
script.setAttribute(“src”, url);
window["callback"+rnd]=func;
script.setAttribute(“id”, “jsonscript”);
document.getElementsByTagName(“head”)[0].appendChild(script);
}
回调函数:
function parseDZList(json){
var show = document.getElementById(“show”);
var Status = json.StatusInfo.Status;
var items = json.Items;
for (var i = 0; i < items.length; i++) {
var ZIMG=items[i].ZIMG
ZIMG=ZIMG.replace(“{0}”,”64×64″)
show.innerHTML += ”
“;
}
}
页面调用:
window.onload = function(){
getJSON(“http://api.zhui.cn/content/ZIDList.json”,parseDZList);
}
后来在群里分享时Along对var rnd=parseInt(Math.random()*1e8)提出自己的观点,并提示可以用生成数组的方式来处理,更大程度上避免了碰撞.不过还好这个只是为了避免缓存,不用太花心思.为了方便我还是使用了数组。
然后小肥猪(冯恒),在群里发了一段代码:
$getJSON = function(url,fun){
var s = document.createElement(‘script’);
s.src = url;
var callback = ‘callback’+ (+new Date());
window[callback] = fun;
document.body.appendChild(s);
}
这个主要是改良了随机数(小小提示下哦,这个代码没有实现JSONP的功能哦);
于是融合上面的代码后最终代码如下:
定义函数:
function getJSON(url, func){
if (!document.getElementById) {
return false;
}
if (document.getElementById(“jsonscript”)) {
var oldscript = document.getElementsByTagName(“script”);
for (var i = 0; i < oldscript.length; i++) {
if (oldscript[i].getAttribute(“src”) == url) {
oldscript.parentNode.removeChild(oldscript);
}
}
}
var script = document.createElement(“script”);
var callback = ‘callback’+ (+new Date());
url+=”?jsoncallback=”+callback;
script.setAttribute(“src”, url);
window[callback]=func;
script.setAttribute(“id”, “jsonscript”);
document.getElementsByTagName(“head”)[0].appendChild(script);
}
回调函数:
function parseDZList(json){
var show = document.getElementById(“show”);
var Status = json.StatusInfo.Status;
var items = json.Items;
for (var i = 0; i < items.length; i++) {
var ZIMG=items[i].ZIMG
ZIMG=ZIMG.replace(“{0}”,”64×64″)
show.innerHTML += “<li><img src=”+ZIMG+” />”+items[i].ZName+”</li>”;
}
}
页面调用:
window.onload = function(){
getJSON(“http://api.zhui.cn/content/ZIDList.json”,parseDZList);
}
终于松了一口气~
![]()
演示地址:http://www.showfan.cn/demo/getJSON.html
在上一篇简单的JavaScript缓动效果的效果上加入暂停和继续;
重点在于:暂停时记录一下当前的动作,留着点击继续用
DEMO:http://showfan.cn/demo/moveElement.html
难点:计算运动过程中的位移
function moveElement(elementID,final_x,final_y,interval){
if(!document.getElementById) return false;
if(!document.getElementById(elementID)) return false;
var elem=document.getElementById(elementID);
var xpos=parseInt(elem.style.left);
var ypos=parseInt(elem.style.top);
if(xpos==final_x&&ypos==final_y){
return false;
}
if(xpos
var dist=Math.ceil((final_x-xpos)/10)
xpos=xpos+dist;
}
if(xpos>final_x){
var dist=Math.ceil((xpos-final_x)/10)
xpos=xpos-dist;
}
if(ypos
var dist=Math.ceil((final_y-ypos)/10)
ypos=ypos+dist;
}
if(ypos>final_y){
var dist=Math.ceil((ypos-final_y)/10)
ypos=ypos-dist;
}
elem.style.left=xpos+”px”;
elem.style.top=ypos+”px”;
var repeat=”moveElement(‘”+elementID+”‘,”+final_x+”,”+final_y+”,”+interval+”)”;
timer=setTimeout(repeat,interval);
}
期待已久的开奖日终于到来,偶滴大名也在获奖名单上面啊~~只不过不知道是几等奖,真希望是一等奖哇(*^__^*) ……
~~~估计是三等奖~~~




