如何在jQuery中重置延迟时间?

4

我正在制作一个老虎机,我想在有人点击添加或减少行时显示行。 我正在使用以下代码; 问题是当有人快速点击(比延迟时间更快)时,它会产生比预期更大的延迟。 这是演示(和 JSFiddle

Bug

function arrowNumbers(id,min,max,difference){
 if ((min === undefined) || (min < 0)){
  min = 1;
 }
 if((difference === undefined)) {
  difference = 1;
 }
 var previousArrow = $('.'+id+' .previous');
 var nextArrow = $('.'+id+' .next');

 var screenNumbers = $('.'+id+' span');
 var actualNumber = $('.'+id+' span').text();

 var n = actualNumber;

 previousArrow.click(function(){
  if (n>min){
   if (parseInt(difference)>=parseInt(n))
    n = min;
   else
    n = parseInt(n)-parseInt(difference);
   showNumber(n);
   if (id=='line')
    showLines(n);
  }
 });

 nextArrow.click(function(){
  if (n<max){
   if (parseInt(difference)+parseInt(n)>max)
    n = max;
   else
    n = parseInt(n)+parseInt(difference);
   showNumber(n);
   if (id=='line')
    showLines(n);
  }
 });

 function showNumber(n){
  screenNumbers.text(n);
 }
}

function showLines(lines){
 var container = 'lines';
 var t = 1000;
 switch (lines) {
  case 20: $('.'+container+' .l.l-20').show(0).delay(t).hide(0);
  case 19: $('.'+container+' .l.l-19').show(0).delay(t).hide(0);
  case 18: $('.'+container+' .l.l-18').show(0).delay(t).hide(0);
  case 17: $('.'+container+' .l.l-17').show(0).delay(t).hide(0);
  case 16: $('.'+container+' .l.l-16').show(0).delay(t).hide(0);
  case 15: $('.'+container+' .l.l-15').show(0).delay(t).hide(0);
  case 14: $('.'+container+' .l.l-14').show(0).delay(t).hide(0);
  case 13: $('.'+container+' .l.l-13').show(0).delay(t).hide(0);
  case 12: $('.'+container+' .l.l-12').show(0).delay(t).hide(0);
  case 11: $('.'+container+' .l.l-11').show(0).delay(t).hide(0);
  case 10: $('.'+container+' .l.l-10').show(0).delay(t).hide(0);
  case 9: $('.'+container+' .l.l-9').show(0).delay(t).hide(0);
  case 8: $('.'+container+' .l.l-8').show(0).delay(t).hide(0);
  case 7: $('.'+container+' .l.l-7').show(0).delay(t).hide(0);
  case 6: $('.'+container+' .l.l-6').show(0).delay(t).hide(0);
  case 5: $('.'+container+' .l.l-5').show(0).delay(t).hide(0);
  case 4: $('.'+container+' .l.l-4').show(0).delay(t).hide(0);
  case 3: $('.'+container+' .l.l-3').show(0).delay(t).hide(0);
  case 2: $('.'+container+' .l.l-2').show(0).delay(t).hide(0);
  case 1: $('.'+container+' .l.l-1').show(0).delay(t).hide(0);
 }
}

arrowNumbers('line',1,20);
.lines {
  width: 500px;
  height: 200px;
}

.lines > .l { width:50px; height: 50px; color: #fff; float: left; background: #000; margin: 10px 0 0 0; display: none; }
.lines > .l:nth-child(2n){ background: rgba(0,0,0,.5); }

/* */

.line {
  color: #fff;
  font-size: 30px;
  width: 300px;
  height: 100px;
}

.line > .previous, .line > .next {
  width: 100px;
  height: 100%;
  background: blue;
  float: left;
}

.line > span {
  width: 100px;
  height: 100%;
  background: green;
  float: left;
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="lines">
 <div class="l l-1">1</div>
 <div class="l l-2">2</div>
 <div class="l l-3">3</div>
 <div class="l l-4">4</div>
 <div class="l l-5">5</div>
 <div class="l l-6">6</div>
 <div class="l l-7">7</div>
 <div class="l l-8">8</div>
 <div class="l l-9">9</div>
 <div class="l l-10">10</div>
 <div class="l l-11">11</div>
 <div class="l l-12">12</div>
 <div class="l l-13">13</div>
 <div class="l l-14">14</div>
 <div class="l l-15">15</div>
 <div class="l l-16">16</div>
 <div class="l l-17">17</div>
 <div class="l l-18">18</div>
 <div class="l l-19">19</div>
 <div class="l l-20">20</div>
</div>

<div class="line">
  <div class="previous">
    <div class="arrow">pre</div>
  </div>
 <span>1</span>
 <div class="next">
   <div class="arrow">next</div>
 </div> 
</div>


你能添加一个 jsfiddle 吗? - rrk
1
这是因为.delay()事件在队列中“堆叠”并且不会在新调用时被取消。请查看此问题可能是重复的)来解决这个问题。 - Spencer Wieczorek
@RejithRKrishnan 抱歉耽搁了,这是fiddle链接 - agustin
2个回答

3

delay()并不适合停止和启动。相反,使用setTimeout和clearTimeout。

将您的showLines函数替换为以下内容:

var line_timers = {};
function showLines(lines){
    var container = 'lines';
    var t = 1000;
    for(var i=1;i<=20;i++) {
        var selector = '.'+container+' .l.l-' + i;
      clearTimeout(line_timers[selector]);
      if(i<=lines){
        $(selector).show(0);
        line_timers[selector]=setTimeout((function(x){
            return function(){
            $(x).hide(0);
          }
        })(selector),t);
      } else {
        $(selector).hide(0);
      }
    }
}

Fiddle: https://jsfiddle.net/trex005/sm14hn79/


这里只需在您的fiddle中替换即可:https://jsfiddle.net/trex005/0f0rdoh7/2/ - trex005

1
尝试执行 dequeue():
function showLines(lines){
    var container = 'lines';
    var t = 1000;
    $('.' + container).find('.l').dequeue().hide();
    switch() ...
}

另一种选择是用淡入淡出/动画替换延迟、显示和隐藏,使用setTimeout并简单地使用stop()和clearTimeout()。

1
他在switch语句中使用fallthrough来显示1行到尽头的代码,但这可以通过while(lines--)来解决。 - trex005
@trex005 啊,没注意到缺少了break语句 :) 谢谢! - Alex
谢谢@Alex,但也许我应该尝试使用您提到的淡入/淡出动画效果。这是使用dequeue()发生的:http://i.imgur.com/NBkFBVK.gif - agustin
@arglab,是的,那看起来不太好看! - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接