0

我有一个我认为是关于 jQuery 中数组的一些基本问题,但我很难过 - 我想做的是创建许多 DOM 元素数组,每个数组的索引号相等,访问它们索引,然后根据该索引执行 jQuery 方法。

例如,我想对第一个数组的成员 i 执行单击操作,并且 i 将针对其他数组成员的相应 i。所以,在下面的例子中,点击arrayOne[1]只会影响arrayTwo[1]和arrayThree[1],点击arrayOne[2]只会影响arrayTwo[2]、arrayThree[2]等等。

我尝试使用“for 循环”、.each() 方法、.map() 并使用 jQuery.each() 方法,但没有任何效果。要么所有键/值成员都受到影响,要么只有一个键/值成员受到影响。因为我已经尝试了很多东西,所以我给出了一个有代表性的问题集,而不是一个特定的问题集,希望这足以解决我的问题。

var arrayOne=['.selectorOne_a', '.selectorOne_b', '.selectorOne_c'];

var arrayTwo=['.selectorTwo_a', '.selectorTwo_b', '.selectorTwo_c'];

var arrayThree=['.selectorThree_a', '.selectorThree_b', '.selectorThree_c'];

for(i=0; i<=arrayOne.length-1; i++){ 
     $(arrayOne[i]).click(function(){
          $(arrayTwo[i]).show();
          $(arrayThree[i]).hide();
     });//click
}

我意识到 for 循环不是这样做的正确方法,但它是我尝试过的代表性方法......应该很简单,对吧?我不知道这是否属于多维数组、散列、what-have-you 的范畴,因此任何关于导航这些概念的建议或教程链接也将不胜感激。我希望这是有道理的,我将不胜感激任何建议。

谢谢!

4

4 回答 4

1

在您正在创建的单击处理程序中,您正在引用i在函数外部定义的变量,并且在响应单击调用处理程序时i将是循环结束时的任何内容,for而不是引用适当的相关元素。您可以通过引入闭包来解决此问题:

for(i=0; i < arrayOne.length; i++){
   (function(i){
      $(arrayOne[i]).click(function(){
          $(arrayTwo[i]).show();
          $(arrayThree[i]).hide();
      });
   })(i);
}

当一个 JS 函数运行时,它可以访问其包含范围内的变量,即使该包含范围是一个已经完成执行的函数。因此,我在上面介绍的匿名函数在for循环的每次迭代中都会被调用,并且它的i参数仍然可供您传递给的函数访问.click()

(另请注意,您的for条件应该是i < arrayOne.length,而不是i<=arrayOne-1- 您不能从数组中减去 1。)

由于您使用的是 jQuery,因此您可以以更整洁的方式执行此操作:

$.each(arrayOne, function(i,val) {
     $(arrayOne[i]).click(function(){
          $(arrayTwo[i]).show();
          $(arrayThree[i]).hide();
     });
});

在我看来,一个更好的整体解决方案是放弃使用数组的想法。以某种方式关联 html 结构中的元素,然后在单击处理程序中使用 DOM 遍历方法来查找要显示和隐藏的相关元素。如果您更新了您的问题以显示您的近似 html 结构,我可以就此提供进一步的建议。

于 2012-07-16T01:52:04.893 回答
0

在遵循 nnnnnn 的建议之后,这是我用来解决问题的最终代码 - 它运行良好,我可以根据需要修改它以在我的标记中创建类似的部分,这是为流畅的响应而构建的。需要注意的一点是我不能使用 css sprites 来创建翻转状态,因为这会涉及到一些不利的绝对定位,所以我决定在 jQuery/javascript 中创建交换图像效果。

    function createClick2(){

    // clickElements are the clickable images which trigger all subsequent actions
    var clickElements= ['.subheader_li_header1 img','.subheader_li_header2 img','.subheader_li_header3 img'];

    //once clickElements are clicked, a specific list appears underneath each clickElement member. These lists are class members of the listShow array
    var listShow= ['.subheader_ul_anim1','.subheader_ul_anim2','.subheader_ul_anim3'];

    // when clickElements are hovered over, an image is swapped- this is the imgSwapOver array
    var imgSwapOver=['img/sidebar_create_over.png','img/sidebar_develop_over.png','img/sidebar_design_over.png'];

    //on mouse out, or double tap, (depending on the device) the image is swapped back in.
    var imgSwapUp=['img/sidebar_create_up.png','img/sidebar_develop_up.png', 'img/sidebar_design_up.png'];

    // counter for holding click information
    var clickCount=0;

    $.each(clickElements, function(i,val) {

        $(clickElements[i]).click(function(){ 
            clickCount++;
            if(clickCount==1){          
                $(listShow[i]).show('slow', function(){
                    $(this).css("display","block");
                    $(clickElements[i]).attr("src", imgSwapOver[i]);//concession for mobile browser

                });//show
            }//if
            else if(clickCount==2){
                $(listShow[i]).hide('slow', function(){
                    $(this).css("display","none");
                    });//hide
                $(clickElements[i]).attr("src", imgSwapUp[i]);//concession for mobile browser
                    clickCount=0;
            }//else if
                }).hover(function(){$(clickElements[i]).attr("src", imgSwapOver[i]); },function(){$(clickElements[i]).attr("src", imgSwapUp[i]); 

                });//hover          
    });//each
}//createClick2
于 2012-07-16T16:54:06.440 回答
0

我认为在这种情况下,您还可以使用其他方式来实现您的目标。您可以找出它们的索引值并使用它来定位对应的 div。

看一个简单的演示

<div class="Array1">
    <div class="selectorOne_a">Array1 a</div>
    <div class="selectorOne_b">Array1 b</div>
    <div class="selectorOne_c">Array1 c</div>
</div>
<div class="Array2">
    <div class="selectorTwo_a">Array2 a</div>
    <div class="selectorTwo_b">Array2 b</div>
    <div class="selectorTwo_c">Array2 c</div>
</div>
<div class="Array3">
    <div class="selectorThree_a">Array2 a</div>
    <div class="selectorThree_b">Array2 b</div>
    <div class="selectorThree_c">Array2 c</div>
</div>

jquery ccode

$(".Array1 div").click(function() {
   index = $(this).index();
   $(".Array2 div:eq("+ index +")").css('background-color','red');//You can do show/hide or add class etc.
   $(".Array3 div:eq("+ index +")").css('background-color','green');
});

​</p>

于 2012-07-16T01:57:45.513 回答
0

这是一件很奇怪的事情,但如果有必要,那么您的循环方法肯定是可行的。但是,您需要采取措施确保事件处理程序获取正确的i. 如您所写,i每个处理程序触发时的值不一定是i处理程序到位时的值。

有多种方法可以解决此问题。

闭包

在循环的每次迭代中,形成一个“闭包”,它 (a) 捕获 的值i并 (b) 返回一个成为实际事件处理程序的函数。

var arrayOne = ['.selectorOne_a', '.selectorOne_b', '.selectorOne_c'];
var arrayTwo = ['.selectorTwo_a', '.selectorTwo_b', '.selectorTwo_c'];
var arrayThree = ['.selectorThree_a', '.selectorThree_b', '.selectorThree_c'];
for(i=0; i<=arrayOne.length-1; i++) {
     $(arrayOne[i]).on('click', function(n) {
          return function() {
              $(arrayTwo[n]).show();
              $(arrayThree[n]).hide();
          }
     })(i);
}

为了清楚起见,我n在闭包中使用了“i”。它可能更典型,虽然不是很清楚,可以i全部使用。

。数据()

您可以使用 jQuery 的.data()方法让 DOM 元素“意识到”它们的i值。

var arrayOne = ['.selectorOne_a', '.selectorOne_b', '.selectorOne_c'];
var arrayTwo = ['.selectorTwo_a', '.selectorTwo_b', '.selectorTwo_c'];
var arrayThree = ['.selectorThree_a', '.selectorThree_b', '.selectorThree_c'];
for(i=0; i<=arrayOne.length-1; i++) {
     $(arrayOne[i]).data('index', i).on('click', function() {
        var i = $(this).data('index');
        $(arrayTwo[i]).show();
        $(arrayThree[i]).hide();
     });
}

。每个()

您可以使用该jQuery.each()方法来形成循环。

var arrayOne = ['.selectorOne_a', '.selectorOne_b', '.selectorOne_c'];
var arrayTwo = ['.selectorTwo_a', '.selectorTwo_b', '.selectorTwo_c'];
var arrayThree = ['.selectorThree_a', '.selectorThree_b', '.selectorThree_c'];
$.each(arrayOne, function(i) {
     $(this).on('click', function() {
        $(arrayTwo[i]).show();
        $(arrayThree[i]).hide();
     });
});

这可能是最简单的方法。虽然看起来不一样,但实际上和形成闭包非常相似,只是细节由 jQuery 处理。

于 2012-07-16T02:56:39.753 回答