使用循环来定义多个JQuery函数

时间:2016-09-11 16:52:30

标签: javascript jquery html

我正在尝试创建一个带有标签按钮的页面,可以根据标签显示/隐藏元素。 这是我的第一个没有循环的版本:

https://jsfiddle.net/Pokipsy/uu7y3x2x/



$(document).ready(function(){
    $(".showall").click(function(){
        $(".item").show();
        $(".filter").text("All elements")
    });
    $(".show.a").click(function(){
    		$(".item").hide();
        $(".item.a").show();
        $(".filter").text("Tag: a")
    });
    $(".show.b").click(function(){
    		$(".item").hide();
        $(".item.b").show();
        $(".filter").text("Tag: b")
    });
    $(".show.c").click(function(){
    		$(".item").hide();
        $(".item.c").show();
        $(".filter").text("Tag: c")
    });
});

.clickable:hover {
    cursor: pointer;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul>
<li class="clickable showall">all</li>
<li class="clickable show a">a</li>
<li class="clickable show b">b</li>
<li class="clickable show c">c</li>
</ul>

<h3 class="filter">
All elements
</h3>
<ul>
<li class="a item">first a</li>
<li class="b item">second b</li>
<li class="a b item">third a b</li>
<li class="c item ">fourth c</li>
<li class="c b item">fifth c b</li>
</ul>
&#13;
&#13;
&#13;

它可以工作,但是如果标签太多,这个策略会生成一个非常长的代码,所以我尝试使用循环来制作一个与标签数组一起使用的更短的代码:

https://jsfiddle.net/Pokipsy/f9uqetnn/1/

&#13;
&#13;
$(document).ready(function(){
    $(".showall").click(function(){
        $(".item").show();
        $(".filter").text("All elements")
    });
    var tags = [".a",".b",".c"]; 
    
    for(i = 0; i < 3; i++) {
    x=tags[i];
    $(".show".concat(x)).click(function(){
    		$(".item").hide();
        $(".item".concat(x)).show();
        $(".filter").text("Tag: ".concat(x))
    		});
    }
});
&#13;
.clickable:hover {
    cursor: pointer;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul>
<li class="clickable showall">all</li>
<li class="clickable show a">a</li>
<li class="clickable show b">b</li>
<li class="clickable show c">c</li>
</ul>

<h3 class="filter">
All elements
</h3>
<ul>
<li class="a item">first a</li>
<li class="b item">second b</li>
<li class="a b item">third a b</li>
<li class="c item ">fourth c</li>
<li class="c b item">fifth c b</li>
</ul>
&#13;
&#13;
&#13;

但它不起作用:显然,即使我点击了第一个元素,它总是会识别出对数组最后一个元素的点击。我无法看到jQuery的问题吗?

4 个答案:

答案 0 :(得分:2)

每次迭代都会覆盖x循环中的变量for,因此您需要锁定另一个闭包内部。另外,我不知道concat()应该做什么,我从来没有看到它与字符串一起使用。只需在JavaScript中使用+ :.

查看您的更新演示:https://jsfiddle.net/eddd36ma/1/

for (i = 0; i < tags.length; i++) {
    (function(x) {
        $(".show" + x).click(function() {
            $(".item").hide();
            $(".item" + x).show();
            $(".filter").text("Tag: " + x)
        });
    })(tags[i]);
}

顺便说一句,还有forEach method以函数作为参数,所以它比for更容易使用,因为tag变量是在每次迭代中确定范围:

tags.forEach(function(tag) {
    $(".show" + tag).click(function() {
        $(".item").hide();
        $(".item" + tag).show();
        $(".filter").text("Tag: " + tag)
    });
});

请参阅演示:https://jsfiddle.net/eddd36ma/3/

答案 1 :(得分:1)

你可以尝试这样的事情

1-而不是showall班级使用show代替所有li.show点击事件

2-制作您拥有的班级名称数组

3-循环数组并在类成立时中断

$(document).ready(function(){
    var ClassesArray = ["a" , "b" , "c"];
    $("li.show").click(function(){
        for ( var i = 0; i < ClassesArray.length; i++ ){
            if ( $(this).hasClass( ClassesArray[i] ) ){
              $(".item").hide();
              $(".item."+ClassesArray[i]).show();
              $(".filter").text("Tag: "+ ClassesArray[i]);
              break;
            }else{
              $(".item").show();
              $(".filter").text("All elements");
            }
        } 
    });
});
.clickable:hover {
    cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul>
<li class="clickable show">all</li>
<li class="clickable show a">a</li>
<li class="clickable show b">b</li>
<li class="clickable show c">c</li>
</ul>

<h3 class="filter">
All elements
</h3>
<ul>
<li class="a item">first a</li>
<li class="b item">second b</li>
<li class="a b item">third a b</li>
<li class="c item ">fourth c</li>
<li class="c b item">fifth c b</li>
</ul>

  

注意:使用此代码,您可以根据需要添加其他类var ClassesArray = ["a" , "b" , "c" , "d" , "e" , ....];和   代码可以正常工作。

答案 2 :(得分:0)

问题不在于jQuery,问题在于逻辑和for循环。正如OP注意到,click处理程序总是使用最后一个不奇怪的元素。到点击时,循环结束,x具有最后一个元素值。解决问题的正确方法是将x=tags[i]包装在函数中。这样的事情。

$(document).ready(function(){
    $(".showall").click(function(){
        $(".item").show();
        $(".filter").text("All elements")
    });
    var tags = [".a",".b",".c"]; 
    
    for(i = 0; i < 3; i++) {
    //x=tags[i];
    (function(x){
    $(".show".concat(x)).click(function(){
    		$(".item").hide();
        $(".item".concat(x)).show();
        $(".filter").text("Tag: ".concat(x))
    		});
    }(tags[i]));
    }
});
.clickable:hover {
    cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul>
<li class="clickable showall">all</li>
<li class="clickable show a">a</li>
<li class="clickable show b">b</li>
<li class="clickable show c">c</li>
</ul>

<h3 class="filter">
All elements
</h3>
<ul>
<li class="a item">first a</li>
<li class="b item">second b</li>
<li class="a b item">third a b</li>
<li class="c item ">fourth c</li>
<li class="c b item">fifth c b</li>
</ul>

答案 3 :(得分:-1)

你也可以这样做

<强> HTML:

<ul class="clickableParent">
  <li data-tag="selectAll" class="clickable">all</li>
  <li data-tag="a" class="clickable">a</li>
  <li data-tag="b" class="clickable">b</li>
  <li data-tag="c" class="clickable">c</li>
</ul>

<h3 class="filter">
All elements
</h3>
<ul class="filterItemsParent">
  <li class="a item">first a</li>
  <li class="b item">second b</li>
  <li class="a b item">third a b</li>
  <li class="c item ">fourth c</li>
  <li class="c b item">fifth c b</li>
</ul>

<强> JQuery的

$(document).ready(function(){
    var filterItemsParent = $(".filterItemsParent");
    var clickableParent = $(".clickableParent");
    var filter = $(".filter");


  clickableParent.on("click", ".clickable", function () {
    var self = $(this);
    var tag = self.data("tag");
    filter.text("Tag: " +  tag);
    tag = (tag !== "selectAll")? "." + tag : ".item";  
    filterItemsParent.children().hide().end()
        .children(tag).fadeIn();
  });
});

JSFIDDLE的演示!