如何重启循环javascript循环

时间:2015-02-09 00:27:51

标签: javascript jquery html css toggle

我不知道如何使标题更清晰,即使问题本身对我来说似乎很清楚。

我一直在使用这个jQuery插件:

http://felix-kling.de/blog/2011/04/14/jQuery-Function-Toggle-plugin/

以弥补在jQuery中已弃用和删除的切换功能。

然后我有以下功能:

<script>
$( document ).ready(function() {
    $("span.letra").funcToggle('click',     
        function() {$(this).addClass("ex1");},
        function() {$(this).removeClass("ex1").addClass("ex2")},
        function() {$(this).removeClass("ex2").addClass("ex3")},
        function() {$(this).removeClass("ex3")}
    );
});
</script>

我使用类是因为我将这个逻辑应用于许多元素,尽管我只希望每次单击它们时单击它们。

每个类为元素添加不同的背景颜色。

现在,在元素之后,我有一个“全部清除”按钮,这将删除每个元素的每个类,将它们全部恢复到“未被点击”的状态。

<script>
$( document ).ready(function() {
    $("span.limpar").click(     
        function() {$("span.letra").removeClass("ex1 ex2 ex3");}
    );
});
</script>

现在,正如您在上面所看到的,此按钮的作用是删除任何元素可能具有的每个类。

现在我的问题:

假设我单击一个元素两次。最后,被点击的元素应用了“ex2”类。

现在让我们假设我点击“全部清除”按钮,激活上面的第二个脚本。它会删除我之前通过点击应用的“ex2”类。

现在,如果我再次点击相同的元素,点击就会像第三次点击一样,激活funcToggle脚本中的第三个功能。

我想要的是不仅清除所有相关元素中的类的代码,还重新启动funcToggle脚本,因此任何单击已经单击的元素都将注册为该序列中的第一次单击。

3 个答案:

答案 0 :(得分:1)

您可以使用class或使用data-*属性。

使用data-*属性更容易,因为您使用单值data-ex attr。在使用类时,你需要做复杂的东西来匹配确切的className,替换正确的类(保持其他类不变)等。

使用data- *属性(最简单):

var $letra = $("span.letra");

$letra.click(function(){
  $(this).attr('data-ex', function(i, v){
    return v? ++v%4 : 1;
  });
});

$('.limpar').click(function(){
  $letra.attr("data-ex", "");
});
.letra{
    cursor:pointer;
    display:inline-block;
    padding:20px;
    background:#eee;
    margin:10px;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
}

[data-ex='1']{background:yellow;}
[data-ex='2']{background:orange;}
[data-ex='3']{background:red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button class="limpar">LIMPAR</button><br>

<span class="letra">Letra</span>
<span class="letra">Letra</span>
<span class="letra">Letra</span>

使用class:

所以你有三个课程ex1ex2ex3

使用jQuery添加一个虚拟ex0
(P.S:如果你想要你可以使用默认样式设置CSS中ex0类的样式。)
为什么?因为您可以读取ex*类中的数字,请增加该数字,并用增加的数字替换该类。
使用提醒操作符(模数)%4来循环您的三个类:

var $letra = $("span.letra");

$letra.addClass("ex0").click(function(){ // Assign 'ex0' Class and Click listener
  $(this).attr('class', function(i, v){  // Modify Class Value...
    return v.replace(/ex\d+/, "ex"+ (++v.match(/ex(\d+)/)[1] % 4));
  });
});

$('.limpar').click(function(){
  $letra.attr("class", function(i, v){
    return v.replace(/ex\d+/, "ex0"); // Set back to the dummy 'ex0' Class
  });
});
.letra{
  display:inline-block;
  padding:20px;
  background:#eee;
  margin:10px;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

.ex1{background:yellow;}
.ex2{background:orange;}
.ex3{background:red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button class="limpar">LIMPAR</button><br>


<span class="letra">ex0</span>
<span class="letra">ex0</span>
<span class="letra ex1">ex1</span>
<span class="letra ex2">ex2</span>
<span class="letra ex3">ex3</span>

答案 1 :(得分:1)

也许你使用funcToggle还有另一个原因,但它似乎更像是一种障碍,而不是对这项工作的帮助。

这是另一种方法。

$('span.letra').on('click', function() {
  var $this = $(this);
  if($this.is('.ex1,.ex2,.ex3')) {
    $this.filter('.ex3').toggleClass('ex3');
    $this.filter('.ex2').toggleClass('ex2 ex3');
    $this.filter('.ex1').toggleClass('ex1 ex2');
  }else{
    $this.toggleClass('ex1');
  }
});

将状态存储在一个地方(就像元素上的类集合)通常比尝试保持多个系统同步更有利于你的理智。

那就是说,如果你想减少重复次数,你可以这样做:

$('span.letrb').on('click', function() {
  var $this = $(this);
  var ex = (1 + parseInt($this.data('ex') || 0)) % 4;
  $this.data('ex', ex);
  $this.removeClass('ex1 ex2 ex3');
  if (ex > 0) {
    $this.addClass('ex'+ex);
  }
});

这要求您记得同时重置数据和类:

$('span.letrb').removeClass('ex1 ex2 ex3').data('ex', 0);

答案 2 :(得分:0)

尝试

(function cycle(elem, clear, arr) {
    // clear classes , reset `cycle`
    clear.one("click.toggle", function () {
        console.log("clear all");
        elem.removeClass(arr.join(" "))
        .clearQueue("toggle").trigger("click.toggle")
    });
    return $.when(elem.queue("toggle", $.map(arr.concat($.noop())
        , function (val, key) {
            return function (next) {
                return $(this).one("click.toggle", function (e) {
                    // add current class, remove previously added class,
                    // call next item in `toggle` queue
                    return $(e.target).addClass(val).removeClass(arr[key - 1]) 
                           && next()
                });
            }
        })
    // return `toggle` promise, `clear`
    ).dequeue("toggle").promise("toggle"), clear, arr)
        .then(function (elem, clear, arr) {
        // `cycle` done , do stuff ,
        // remove added classes , reset `cycle`
        console.log("done");
        clear.off("click.toggle");
        return elem.removeClass(arr.join(" ")) && cycle(elem, clear, arr) 
    });
}($("span.letra"), $("span.limpar"), ["ex1", "ex2", "ex3"]));

&#13;
&#13;
(function cycle(elem, clear, arr) {
    clear.one("click.toggle", function () {
        console.log("clear all");
        elem.removeClass(arr.join(" "))
        .clearQueue("toggle").trigger("click.toggle")
    });
    return $.when(elem.queue("toggle", $.map(arr.concat($.noop()), function (val, key) {
        return function (next) {
            return $(this).one("click.toggle", function (e) {
                return $(e.target).addClass(val).removeClass(arr[key - 1]) && next()
            });
        }
    })).dequeue("toggle").promise("toggle"), clear, arr)
        .then(function (elem, clear, arr) {
        console.log("done");
        clear.off("click.toggle");
        return elem.removeClass(arr.join(" ")) && cycle(elem, clear, arr) 
    });
}($("span.letra"), $("span.limpar"), ["ex1", "ex2", "ex3"]));
&#13;
.ex1 {
    background-color:red;
}
.ex2 {
    background-color:green;
}
.ex3 {
    background-color:blue;
}
.letra {
    width:150px;
    height:150px;
    border:1px solid purple;
    display:block;
    font-size: 36px;
    text-align:center;
}
.limpar {
    background:yellow;
    border:1px solid #000;
    display:block;
    width:136px;
    padding:7px;
    margin-top:1px;
    font-size:18px;
    text-align:center;
    
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span class="letra">click</span>
<span class="limpar">clear all</span>
&#13;
&#13;
&#13;