对JQuery在循环中绑定事件的问题理解
对JQuery在循环中绑定事件的问题理解
在昨天写网页时遇到了一个关于jQuery在循环中绑定事件后部分效果失效的问题,在这里分享一下解决方案
1、先上HTML代码:
在这里需要实现的是鼠标经过li时通过jq animate动画动态增加li元素的高同时使兄弟元素高减少,此外每个li都有指定的img图片,当鼠标经过li时触发mouseover事件使相对的img图片显示同时其他兄弟图片隐藏
2、js代码
for(var i=1;i<=5;i++){$(".hoverpart_menu_option").mouseover(function(){$(this).stop().animate({height:"94px"},400).css("background-color","#0055ce").siblings().stop().animate({height:"37px"},400).css("background-color","#ccc");$(this).addClass("option_selected").siblings().removeClass("option_selected");//以下失效$("img.hoverpart_img"+i).addClass("imgSelected").siblings().removeClass("imgSelected");});}
在这标注“以下失效”之前的代码都已经成功绑定了每个li,然而此时img并没有随着切换
于是在JS中间添加alert测试i值:
for(var i=1;i<=5;i++){$(".hoverpart_menu_option").mouseover(function(){$(this).stop().animate({height:"94px"},400).css("background-color","#0055ce").siblings().stop().animate({height:"37px"},400).css("background-color","#ccc");$(this).addClass("option_selected").siblings().removeClass("option_selected");alert("到这里的i值为:"+i);//插这里//以下失效$("img.hoverpart_img"+i).addClass("imgSelected").siblings().removeClass("imgSelected");});}
结果弹出:
而且关键是还弹出5次!!!
。。。。此时我的内心是这样的:
于是乎再改alert的位置进行测试:
for(var i=1;i<=5;i++){$(".hoverpart_menu_option").mouseover(function(){alert("到这里的i值为:"+i);//插这里$(this).stop().animate({height:"94px"},400).css("background-color","#0055ce").siblings().stop().animate({height:"37px"},400).css("background-color","#ccc");$(this).addClass("option_selected").siblings().removeClass("option_selected");//以下失效$("img.hoverpart_img"+i).addClass("imgSelected").siblings().removeClass("imgSelected");});}
还是5个6。。。。你怎么不6个6啊!
再改!
for(var i=1;i<=5;i++){alert("到这里的i值为:"+i);//我再插!$(".hoverpart_menu_option").mouseover(function(){$(this).stop().animate({height:"94px"},400).css("background-color","#0055ce").siblings().stop().animate({height:"37px"},400).css("background-color","#ccc");$(this).addClass("option_selected").siblings().removeClass("option_selected");//以下失效$("img.hoverpart_img"+i).addClass("imgSelected").siblings().removeClass("imgSelected");});}
果断问百度爸爸
于是乎找到这篇文章:《深入理解JQuery循环绑定事件》
恍然大悟!!!
始终弹出6, 因为function() {} 并没有被立即解析,直到调用的时候才被解析,立即弹出0, 1, 2, 3,4,5是因为使用了function() {}(index)立即被解析,遇到alert,就立即弹出
于是依瓢画葫芦改了一番代码,
3、如下:
for(var i=1;i<=5;i++){$(".hoverpart_menu_option"+i).bind("mouseover",{index:i},addOne);}function addOne(event){var i=event.data.index;$(this).stop().animate({height:"94px"},400).css("background-color","#0055ce").siblings().stop().animate({height:"37px"},400).css("background-color","#ccc");$(this).addClass("option_selected").siblings().removeClass("option_selected");$("img.hoverpart_img"+i).addClass("imgSelected").siblings().removeClass("imgSelected");}
效果终于正确执行,鼠标滑过li对应图片变化正常同时选项高度变化,内容显示。
4、原理
按照期望的效果是在for五次循环分别给按钮每个li都绑定mouseover事件,但是五遍循环绑定的是mouseover(i)事件,而不是mouseover(1)、mouseover(2)、mouseover(3)……
与此同时给”img.hoverpart_img”+i中绑定的也是i,而不是1到5,因为在绑定的过程中bind的事件处理函数里的代码并没有运行,因此在触发onmoseover事件之前并不知道i等于几,于是乎就出现了上面的测试中弹出五个6的现象
啊哈哈这难不倒我
在这里还有一个javascript的版本,主要是需要闭包解决:
《JavaScript在for循环中绑定事件解决事件参数不同的情况》
5、改装
实际在网页开发过程中代码还可以进一步优化
首先为了方便后台改动,需要微调一下HTML的class:
然后再改js:
$(".hoverpart_menu_option").each(function(index, element) {$(this).mouseover(function(e) {$(this).stop().animate({height:"94px"},400).css("background-color","#0055ce").siblings().stop().animate({height:"37px"},400).css("background-color","#ccc");$(this).addClass("option_selected").siblings().removeClass("option_selected");$("img.hoverpart_img").eq(index).addClass("imgSelected").siblings("img.hoverpart_img").removeClass("imgSelected");});})
在这里我们使用了each()方法即jquery的遍历而不是原声的js的for循环遍历,它方便在于each() 方法规定为每个匹配了元素规定运行的函数,同时可以指定index及选择器的位置,将位置指示给eq()方法使用以依次遍历每个img.hoverpart_img,在这里jquery的each方法是通过js里的call方法来实现的,即调用一个对象的一个方法,以另一个对象替换当前对象,通俗来讲就是改变上下文的this指针从而达到改变指向的效果最终实现遍历不同位置。
大功告成,洗洗睡了!
标签:
相关文章
-
无相关信息