如何重新开始循环javascript循环
How to restart cycling javascript cycle
我不知道如何让标题更清楚,尽管问题本身对我来说已经足够清楚了。
我一直在使用这个 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>
我使用 classes 是因为我将此逻辑应用于许多元素,尽管我只希望被点击的元素在每次被点击时都经历循环。
每个 class 向元素添加一个不同的 background-color。
现在,在元素之后我有一个 "clean all" 按钮,它将删除每个元素中的每一个 class,将它们全部返回到 "unclicked" 状态。
<script>
$( document ).ready(function() {
$("span.limpar").click(
function() {$("span.letra").removeClass("ex1 ex2 ex3");}
);
});
</script>
正如您在上面看到的那样,现在这个按钮的作用是删除任何元素可能具有的每个 class。
现在解决我的问题:
假设我点击了一个元素两次。最后,单击的元素应用了 "ex2" class。
现在假设我点击了 "clean all" 按钮,激活了上面的第二个脚本。它删除了我之前通过点击应用到它的 "ex2" class。
现在,如果我再次单击 同一元素 ,单击会像 第三次 单击一样进行,激活 funcToggle 中的第三个函数脚本。
我想要的代码不仅能从所有相关元素中清除 classes,还能重新启动 funcToggle 脚本,这样任何对 already-clicked 元素的点击都会注册为首先点击该序列。
您可以使用 class
或使用 data-*
属性。
使用 data-*
属性更容易,因为您使用的是单值 data-ex
属性。在使用 classes 时,你需要做一些复杂的事情来匹配确切的 className,替换正确的 class(保持其他 classes 不变)等
使用 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:
所以你有三个 classes ex1
、ex2
和 ex3
?
添加 jQuery 一个虚拟 ex0
class
(P.S:如果需要,您可以使用默认样式在 CSS 中设置 ex0
class 的样式。
为什么? 因为您可以从 ex*
class 中读取数字,增加该数字并将 class 替换为增加的数字。
使用提醒运算符(模数)%4
循环你的三个 classes:
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>
尝试
(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"]));
(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"]));
.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;
}
<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>
也许您使用 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);
我不知道如何让标题更清楚,尽管问题本身对我来说已经足够清楚了。
我一直在使用这个 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>
我使用 classes 是因为我将此逻辑应用于许多元素,尽管我只希望被点击的元素在每次被点击时都经历循环。
每个 class 向元素添加一个不同的 background-color。
现在,在元素之后我有一个 "clean all" 按钮,它将删除每个元素中的每一个 class,将它们全部返回到 "unclicked" 状态。
<script>
$( document ).ready(function() {
$("span.limpar").click(
function() {$("span.letra").removeClass("ex1 ex2 ex3");}
);
});
</script>
正如您在上面看到的那样,现在这个按钮的作用是删除任何元素可能具有的每个 class。
现在解决我的问题:
假设我点击了一个元素两次。最后,单击的元素应用了 "ex2" class。
现在假设我点击了 "clean all" 按钮,激活了上面的第二个脚本。它删除了我之前通过点击应用到它的 "ex2" class。
现在,如果我再次单击 同一元素 ,单击会像 第三次 单击一样进行,激活 funcToggle 中的第三个函数脚本。
我想要的代码不仅能从所有相关元素中清除 classes,还能重新启动 funcToggle 脚本,这样任何对 already-clicked 元素的点击都会注册为首先点击该序列。
您可以使用 class
或使用 data-*
属性。
使用 data-*
属性更容易,因为您使用的是单值 data-ex
属性。在使用 classes 时,你需要做一些复杂的事情来匹配确切的 className,替换正确的 class(保持其他 classes 不变)等
使用 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:
所以你有三个 classes ex1
、ex2
和 ex3
?
添加 jQuery 一个虚拟 ex0
class
(P.S:如果需要,您可以使用默认样式在 CSS 中设置 ex0
class 的样式。
为什么? 因为您可以从 ex*
class 中读取数字,增加该数字并将 class 替换为增加的数字。
使用提醒运算符(模数)%4
循环你的三个 classes:
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>
尝试
(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"]));
(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"]));
.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;
}
<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>
也许您使用 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);